|
rcbench
Servo and ESC test bench: panel, IOmcu and shared C
|
Synchronising two servos that drive one control surface. More...
#include <stdbool.h>#include <stdint.h>Go to the source code of this file.
Data Structures | |
| struct | servo_sync_cfg_t |
| struct | servo_sync_t |
Enumerations | |
| enum | servo_sync_state_t { SERVO_SYNC_RUNNING = 0 , SERVO_SYNC_DONE , SERVO_SYNC_FAULT } |
| enum | servo_sync_fault_t { SERVO_SYNC_FAULT_NONE = 0 , SERVO_SYNC_FAULT_OVERCURRENT , SERVO_SYNC_FAULT_NO_MINIMUM } |
| enum | servo_sync_stage_t { SERVO_SYNC_STAGE_CENTRE = 0 , SERVO_SYNC_STAGE_HIGH , SERVO_SYNC_STAGE_LOW , SERVO_SYNC_STAGE_COUNT } |
| Which of the three measurements the search is on. | |
Functions | |
| void | servo_sync_defaults (servo_sync_cfg_t *cfg, uint16_t centre_us) |
| Defaults for a sync search. | |
| void | servo_sync_init (servo_sync_t *sy, const servo_sync_cfg_t *cfg) |
| Start a sync search at the centre stage. | |
| void | servo_sync_step (servo_sync_t *sy, float total_a, uint32_t now_ms, uint16_t *cmd_a, uint16_t *cmd_b) |
| Advance the search with one reading of the pair's total current. | |
| float | servo_sync_progress (const servo_sync_t *sy) |
| 0..1 across all three stages. | |
Synchronising two servos that drive one control surface.
Dual ailerons, elevator halves, a rudder on two horns: two servos on one surface settle any disagreement between them through the surface. Nothing fails and nothing reports it; both servos push against each other and draw extra current continuously.
The objective is not a position. There is no reference angle. The total current the pair draws is smallest where they stop working against each other, which makes the problem a one-dimensional search per stage.
The two errors separate:
a difference at centre is an offset error -> trim one servo's centre a difference at the ends is a travel error -> scale one servo's throw
Measured at the centre and then at each end, each correction comes from its own measurement. Each end gets its own number: a linkage is not symmetric about centre once a horn and a pushrod are involved, the same reason the limit search measures both ends.
Current cannot show two servos that agree with each other and are both wrong: a surface that is stiff nowhere and sits 5 degrees off. That is a separate measurement with the accelerometer on the surface.
Fed measurements and returning commands, as servo_limit is: the host suite runs it against a modelled pair, and a real pair needs no change here. No firmware calls it.
SPDX-License-Identifier: MIT
| enum servo_sync_fault_t |
| void servo_sync_defaults | ( | servo_sync_cfg_t * | cfg, |
| uint16_t | centre_us ) |
Defaults for a sync search.
| cfg | Configuration to fill. Does nothing when NULL. |
| centre_us | Centre pulse width, us. |
| void servo_sync_init | ( | servo_sync_t * | sy, |
| const servo_sync_cfg_t * | cfg ) |
Start a sync search at the centre stage.
| sy | Search state to initialise. Does nothing when NULL. |
| cfg | Configuration to copy. Does nothing when NULL. |
| float servo_sync_progress | ( | const servo_sync_t * | sy | ) |
0..1 across all three stages.
| sy | Search state. NULL gives 0.0. |
| void servo_sync_step | ( | servo_sync_t * | sy, |
| float | total_a, | ||
| uint32_t | now_ms, | ||
| uint16_t * | cmd_a, | ||
| uint16_t * | cmd_b ) |
Advance the search with one reading of the pair's total current.
Total, not per servo: the quantity minimised is what the two draw together, so one sensor across both outputs is enough.
Writes the two pulse widths to command through cmd_a and cmd_b.
| sy | Search state. |
| total_a | Total current of the pair, A. |
| now_ms | Time of the reading, ms. |
| cmd_a | Out: pulse width for servo A, us. NULL to skip. |
| cmd_b | Out: pulse width for servo B, us. NULL to skip. |