-
Notifications
You must be signed in to change notification settings - Fork 120
Custom pwm output widgets #3668
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Custom pwm output widgets #3668
Conversation
…types of functions
Reviewer's GuideRefactors the servo function editor to delegate to specialized widgets based on the selected function type (motor, generic servo range, GPIO, actuator), introducing new dedicated Vue components for PWM range and motor configuration while preserving and adapting the existing slider-based min/trim/max editor logic. Sequence diagram for motor PWM editing and persistencesequenceDiagram
actor User
participant ServoFunctionMotorEditor
participant AutopilotStore as AutopilotStore
participant Parameter
participant Mavlink2Rest as Mavlink2Rest
User->>ServoFunctionMotorEditor: Open servo function dialog
ServoFunctionMotorEditor->>AutopilotStore: parameter(MOT_PWM_TYPE)
AutopilotStore-->>ServoFunctionMotorEditor: mot_pwm_type_param
ServoFunctionMotorEditor->>AutopilotStore: parameter(MOT_PWM_MIN, MOT_PWM_MAX or *_MIN, *_MAX)
AutopilotStore-->>ServoFunctionMotorEditor: min_param, max_param, trim_param
ServoFunctionMotorEditor->>ServoFunctionMotorEditor: initializeSliderValues()
User->>ServoFunctionMotorEditor: Drag slider thumb
ServoFunctionMotorEditor->>ServoFunctionMotorEditor: onSliderMouseDown(event)
ServoFunctionMotorEditor->>ServoFunctionMotorEditor: calculateValueFromEvent()
ServoFunctionMotorEditor->>ServoFunctionMotorEditor: findClosestThumb()
loop While dragging
User->>ServoFunctionMotorEditor: Move pointer
ServoFunctionMotorEditor->>ServoFunctionMotorEditor: onSliderMouseMove(event)
ServoFunctionMotorEditor->>ServoFunctionMotorEditor: updateThumbValue(event)
ServoFunctionMotorEditor->>ServoFunctionMotorEditor: updateValueBasedOnThumb(value)
ServoFunctionMotorEditor->>ServoFunctionMotorEditor: updateMinTrimMax()
ServoFunctionMotorEditor->>Parameter: update local Parameter.value
end
User->>ServoFunctionMotorEditor: Release mouse button
ServoFunctionMotorEditor->>ServoFunctionMotorEditor: onSliderMouseUp()
ServoFunctionMotorEditor->>Parameter: resolve selected param
ServoFunctionMotorEditor->>Mavlink2Rest: setParam(param.name, value, AutopilotStore.system_id, param.paramType.type)
Mavlink2Rest-->>ServoFunctionMotorEditor: ack
ServoFunctionMotorEditor->>Parameter: param.value = value
Class diagram for new servo function editor componentsclassDiagram
class ServoFunctionEditorDialog {
+Parameter param
+boolean value
+function_type() VueConstructor
}
class ServoFunctionRangeEditor {
+Parameter param
-number minValue
-number trimValue
-number maxValue
-number activeThumb
-boolean isDragging
+trim_param() Parameter
+max_param() Parameter
+min_param() Parameter
+minPercent() number
+trimPercent() number
+maxPercent() number
+getParamByType(type string) Parameter
+calculatePercentage(value number) number
+updateParamValue(type ParamType, newValue number) void
+initializeSliderValues() void
+getThumbPosition(index number) number
+getThumbValue(index number) number
+startDragging(index number) void
+onSliderMouseDown(event MouseEvent) void
+calculateValueFromEvent(event MouseEvent, container HTMLElement) object
+findClosestThumb(value number) number
+onSliderMouseMove(event MouseEvent) void
+onSliderMouseUp() void
+updateThumbValue(event MouseEvent) void
+updateValueBasedOnThumb(value number) void
+updateMin(value string) void
+updateTrim(value string) void
+updateMax(value string) void
+updateParamWithConstraints(value string, param Parameter, min number, max number, property string) void
+onTouchStart(event TouchEvent) void
+onTouchMove(event TouchEvent) void
+onTouchEnd() void
}
class ServoFunctionMotorEditor {
+Parameter param
-number minValue
-number trimValue
-number maxValue
-number activeThumb
-boolean isDragging
+trim_param() Parameter
+max_param() Parameter
+min_param() Parameter
+mot_pwm_type_param() Parameter
+mot_pwm_type() PwmTypes
+mot_pwm_type_is_supported() boolean
+minPercent() number
+trimPercent() number
+maxPercent() number
+getParamByType(type string) Parameter
+calculatePercentage(value number) number
+updateParamValue(type ParamType, newValue number) void
+initializeSliderValues() void
+getThumbPosition(index number) number
+getThumbValue(index number) number
+startDragging(index number) void
+onSliderMouseDown(event MouseEvent) void
+calculateValueFromEvent(event MouseEvent, container HTMLElement) object
+findClosestThumb(value number) number
+onSliderMouseMove(event MouseEvent) void
+onSliderMouseUp() void
+updateThumbValue(event MouseEvent) void
+updateValueBasedOnThumb(value number) void
+updateMin(value string) void
+updateTrim(value string) void
+updateMax(value string) void
+updateParamWithConstraints(value string, param Parameter, min number, max number, property string) void
+onTouchStart(event TouchEvent) void
+onTouchMove(event TouchEvent) void
+onTouchEnd() void
}
class ServoFunctionGpioEditor {
+Parameter param
}
class ServoFunctionActuatorEditor {
+Parameter param
}
class InlineParameterEditor {
+boolean autoSet
+string label
+Parameter param
}
class Parameter {
+string name
+number value
+object paramType
}
class AutopilotStore {
+number system_id
+parameter(name string) Parameter
}
class Mavlink2Rest {
+setParam(name string, value number, systemId number, paramType any) void
}
ServoFunctionEditorDialog --> Parameter : uses
ServoFunctionEditorDialog ..> ServoFunctionRangeEditor : selects
ServoFunctionEditorDialog ..> ServoFunctionMotorEditor : selects
ServoFunctionEditorDialog ..> ServoFunctionGpioEditor : selects
ServoFunctionEditorDialog ..> ServoFunctionActuatorEditor : selects
ServoFunctionRangeEditor *-- InlineParameterEditor : embeds
ServoFunctionMotorEditor *-- InlineParameterEditor : embeds
ServoFunctionRangeEditor ..> Parameter : reads_writes
ServoFunctionMotorEditor ..> Parameter : reads_writes
ServoFunctionRangeEditor ..> AutopilotStore : getParamByType
ServoFunctionMotorEditor ..> AutopilotStore : getParamByType
ServoFunctionRangeEditor ..> Mavlink2Rest : setParam
ServoFunctionMotorEditor ..> Mavlink2Rest : setParam
AutopilotStore <.. ServoFunctionRangeEditor
AutopilotStore <.. ServoFunctionMotorEditor
Mavlink2Rest <.. ServoFunctionRangeEditor
Mavlink2Rest <.. ServoFunctionMotorEditor
Flow diagram for selecting specialized servo function widgetflowchart TD
A[Start with selected servo function param] --> B[Read param.value]
B --> C[Lookup selected option name in param.options]
C --> D{Lowercased name contains substring?}
D -->|contains 'motor'| E[Return ServoFunctionMotorEditor]
D -->|contains 'gpio'| F[Return ServoFunctionGpioEditor]
D -->|contains 'actuator'| G[Return ServoFunctionActuatorEditor]
D -->|contains 'disabled'| H[Return undefined and render no widget]
D -->|none of the above| I[Return ServoFunctionRangeEditor]
E --> J[Dynamic component renders motor editor]
F --> J
G --> J
H --> K[No specialized widget shown]
I --> J
J --> L[User edits PWM via selected widget]
K --> L
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
df041a8 to
6cc37db
Compare
9168d34 to
a21f838
Compare
a21f838 to
2ef8f71
Compare
ES-Alexander
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Niiice!! Will hopefully be some significant improvements for the UX :-)
Various interface suggestions, plus some code and functionality ones.
Some great steps towards being able to do something like this table idea in the longer term :-)
| }, | ||
| trim_param(): Parameter | undefined { | ||
| if (this.mot_pwm_type === PwmTypes.Normal) { | ||
| return autopilot.parameter(`MOT_${this.motor_number}_TRIM`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be nothing, right? There's no trim control for Normal motors (IIRC that's why we needed a different motor type).
| const pretty_name = param_using_this_gpio.name.split('_')[0].toLowerCase().toTitle() | ||
| return `GPIO [${pretty_name}]` | ||
| } | ||
| return `Unknown GPIO ${gpio}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return `Unknown GPIO ${gpio}` | |
| return `GPIO ${gpio} [Unknown]` |
I think consistent formatting would be nicer. Starting with GPIO also makes it easier to find in the list.
| this_servo_gpio(): number | undefined { | ||
| if (!this.servo_number) return undefined | ||
| if (this.board_name?.startsWith('Navigator')) { | ||
| return this.servo_number | ||
| } | ||
| // We are assuming most boards follow the same GPIO numbering scheme as the Pixhawk1 | ||
| // Aux channels start at 50, and Main channels start at 101 | ||
| if (this.servo_number <= 8) { | ||
| return this.servo_number + 100 | ||
| } | ||
| return this.servo_number - 9 + 50 | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to reuse the servo_to_gpio function from PwmSetup.vue?
| <relay-setup | ||
| v-if="function_type_using_this_gpio?.name?.includes('RELAY')" | ||
| :relay-parameter="function_type_using_this_gpio" | ||
| /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there should be a leak-setup here, that allows setting the "logic level when dry" (LEAKn_LOGIC).
We could also add the FS_LEAK_ENABLE failsafe Action parameter, although I'm unsure whether it's better to just point the user to the failsafes page or something...
| <v-col cols="12"> | ||
| <v-alert | ||
| v-if="!has_joystick_function_configured" | ||
| type="error" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unsure whether this should be an error or just a warning, since someone may just want to control an Actuator programatically (e.g. with a Cockpit slider, or some Actions).
That said, I suppose right now it's not possible to do that, so we could make it an error and update it once DO_SET_ACTUATOR support is added?
| <div> | ||
| <v-row class="mb-4"> | ||
| <v-col cols="6"> | ||
| <span class="text-h6">PWM Type</span> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <span class="text-h6">PWM Type</span> | |
| <span class="text-h6">Motor Control Signal (shared)</span> |
Nice to make it clear that this can't be set per-motor, and I feel like the "PWM Type" part is redundant with the MOT_PWM_TYPE description over the dropdown.
Undecided whether "shared" or "all" is better.
| title="Motor Configuration" | ||
| tooltip="Adjust the minimum, trim, and maximum PWM values for this motor" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we make these dynamic based on the selected type? So the title says "Motor Configuration (shared)" when Normal is selected, and just "Motor Configuration" when PWMAngle? And for the tooltip, end with "all motors" and skip the , trim, when Normal, or just end with "this motor" when PWMAngle?
| Normal = 0, | ||
| OneShot = 1, | ||
| OneShot125 = 2, | ||
| Brushed = 3, | ||
| DShot150 = 4, | ||
| DShot300 = 5, | ||
| DShot600 = 6, | ||
| DShot1200 = 7, | ||
| PWMRange = 8, | ||
| PWMAngle = 9, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we expect users to be familiar with these options?
Just curious whether we want PWMAngle to be put second for Sub users, and possibly with some extra text to explain that it supports trim and independent PWM ranges...
| :param="steps_param" | ||
| /> | ||
| </v-col> | ||
| <servo-function-range-editor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| </v-alert> | ||
| </v-col> | ||
| </v-row> | ||
| <servo-function-range-editor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.


adds custom widgets/optiosn for:
regular servo
motors
actuators
lights
gpio
relays
helps #3267
Summary by Sourcery
Introduce specialized editors for different servo function types in the parameter editor dialog to support motor- and GPIO-specific PWM configuration while keeping a generic range editor for other functions.
Enhancements: