Skip to content
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

Make PWM allocation a bit smarter. #9268

Merged
merged 23 commits into from
Sep 8, 2023
Merged

Conversation

mmosca
Copy link
Collaborator

@mmosca mmosca commented Aug 30, 2023

Dynamically allocate servo and motor outputs.

Motors are allocated first and outputs can be assigned as both.

When ensuring enough motors have been allocated for a given mixer setting:

  1. Check if target already has enough outputs set as motor only
  2. Claim those timers as motor only, in case there are issues with the target definition
  3. If more motors are needed, claim additional motors from list of outputs that can be either motor or servo, in order
  4. Once an output is claimed, mark other outputs in that timer as motor only.

Servos are only allocated from timers that have no motors, and servos are only assigned to outputs that have no motors.

Needs configurator update (iNavFlight/inav-configurator#1820) to easily:

  • Allow overriding a timer as motor only/servo only
  • Display timer information in the output list

This opens up the possibility of flexible with outputs on targets, and eventually may open up the possibility of asymetric setups, with different motor protocols on different timers, or different servo refresh rates and pulse width on different timers.

Adding/removing motors in the mixer may reorder outputs, and require re-wiring. We can avoid breaking existing setups by not changing existing targets, but I plan on allowing manually overriding a timer to be MOTOR or SERVO and show timer info on the configurator output display.

Goals:

  • Dynamically allocate motor outputs
  • Add msp command to fetch output + timer info
  • Allow overriding outputs of individual timers
    • add cli command to override timers
    • add timer info to diff / dump
    • Add msp command to override timer from configurator
    • Supports matching legacy target outputs
  • Simplify list of targets
    • Remove _SERVO targets

For the future:

  • Support asymmetric output configurations (quite common in helis):
    • Motors on TIM1 are DSHOT, Motors on TIM2 are MULTISHOT
    • Servos om TIM3 are 1520us 333Hz
    • Servos on TIM4 are 760us (common heli tail servo)

Do you want to build a scale 4 motor bomber model? Easy!

Oh, you want A bicopter with many servos? Of course, you don't need a new target for that!

Are you building a quad with walking spider legs? -- Why? But sure....

Only assign servo output if the timer is not used for a motor.
Only assign a motor output if the timer is not used for a servo.

Needs configurator update and more testing.

Checking resource on the MATEKH743 on the CLI, with 3 motors, servos were correctly assigned to TIM4 outpus,
instead of TIM5, even with outputs sets to MC_SERVO and MC_MOTOR
@mmosca
Copy link
Collaborator Author

mmosca commented Aug 30, 2023

This would have worked with the assignment suggested in #9214.

The following targets already have dual MOTOR/SERVO assignment in MC mode.

AIKONF4
AIRBOTF4
ATOMRCF405NAVI
AXISFLYINGF7PRO
BEEROTORF4
COLIBRI
DALRCF405
FLYWOOF745
GEPRCF722_BT_HD
HAKRCF405V2
HAKRCF722V2
HGLRCF722
IFLIGHTF7_TWING
IFLIGHT_BLITZ_F7_AIO
IFLIGHT_BLITZ_F7_PRO
IFLIGHT_JBF7PRO
KAKUTEF4
KAKUTEF7
MATEKF405
MATEKF722
NEUTRONRCF435SE
NEUTRONRCF435WING
OMNIBUSF4
REVO
RUSH_BLADE_F7
SAGEATF4
SPARKY2
SPEEDYBEEF4
SPEEDYBEEF7
SPRACINGF4EVO
YUPIF4
YUPIF7
ZEEZF7

@mmosca
Copy link
Collaborator Author

mmosca commented Aug 30, 2023

Here is the allocation result on the modified MATEKH743 target in this PR

smix
smix 0 1 12 100 0 -1
smix 1 2 13 100 0 -1

# mmix
mmix 0  1.000 -1.000  1.000 -1.000
mmix 1  1.000 -1.000 -1.000  1.000
mmix 2  1.000  0.000  0.000  0.000

# resource
IO:
----------------------
A00: MOTOR3 OUT <----
A01: FREE 
A02: FREE 
A03: FREE 
A04: FREE 
A05: SPI1 SCK
A06: SPI1 MISO
A07: FREE 
A08: FREE 
A09: SERIAL1 UART TX
A10: SERIAL1 UART RX
A11: USB IN
A12: USB OUT
A13: FREE 
A14: FREE 
A15: BEEPER OUT
B00: MOTOR1 OUT <----
B01: MOTOR2 OUT <----
B02: FREE 
B03: FREE 
B04: FREE 
B05: FREE 
B06: I2C1 SCL
B07: I2C1 SDA
B08: FREE 
B09: FREE 
B10: I2C2 SCL
B11: I2C2 SDA
B12: OSD CS
B13: SPI2 SCK
B14: SPI2 MISO
B15: SPI2 MOSI
C00: ADC CH1
C01: ADC CH2
C02: FREE 
C03: FREE 
C04: FREE 
C05: FREE 
C06: FREE 
C07: SERIAL6 UART RX
C08: SDCARD 
C09: SDCARD 
C10: SDCARD 
C11: SDCARD 
C12: SDCARD 
C13: SPI_PREINIT CS
C14: FREE 
C15: MPU CS
D00: FREE 
D01: FREE 
D02: SDCARD 
D03: FREE 
D04: FREE 
D05: FREE 
D06: FREE 
D07: SPI1 MOSI
D08: FREE 
D09: FREE 
D10: PINIO1 OUT
D11: PINIO2 OUT
D12: SERVO4 OUT <-----
D13: SERVO5 OUT <-----
D14: FREE 
D15: FREE 
E00: FREE 
E01: FREE 
E02: SPI_PREINIT CS
E03: LED1 OUT
E04: LED2 OUT
E05: FREE 
E06: FREE 
E07: FREE 
E08: FREE 
E09: FREE 
E10: FREE 
E11: SPI_PREINIT CS
E12: FREE 
E13: FREE 
E14: FREE 
E15: FREE 

# 

@mmosca
Copy link
Collaborator Author

mmosca commented Aug 30, 2023

@shota3527 can this be a potential problem for the vtol mixer profiles?

Timer ids are needed to correctly replicate pwm allocation logic in the configurator
@mmosca
Copy link
Collaborator Author

mmosca commented Aug 30, 2023

Removing motor 3, frees up timer5 for servos and servos get allocated to PA0 and PA1

mmix
mmix 0  1.000 -1.000  1.000 -1.000
mmix 1  1.000 -1.000 -1.000  1.000

# smix
smix 0 1 12 100 0 -1
smix 1 2 13 100 0 -1

# resource
IO:
----------------------
A00: SERVO3 OUT <----
A01: SERVO4 OUT <----
A02: FREE 
A03: FREE 
A04: FREE 
A05: SPI1 SCK
A06: SPI1 MISO
A07: FREE 
A08: FREE 
A09: SERIAL1 UART TX
A10: SERIAL1 UART RX
A11: USB IN
A12: USB OUT
A13: FREE 
A14: FREE 
A15: BEEPER OUT
B00: MOTOR1 OUT <----
B01: MOTOR2 OUT <----
B02: FREE 
B03: FREE 
B04: FREE 
B05: FREE 
B06: I2C1 SCL
B07: I2C1 SDA
B08: FREE 
B09: FREE 
B10: I2C2 SCL
B11: I2C2 SDA
B12: OSD CS
B13: SPI2 SCK
B14: SPI2 MISO
B15: SPI2 MOSI
C00: ADC CH1
C01: ADC CH2
C02: FREE 
C03: FREE 
C04: FREE 
C05: FREE 
C06: FREE 
C07: SERIAL6 UART RX
C08: SDCARD 
C09: SDCARD 
C10: SDCARD 
C11: SDCARD 
C12: SDCARD 
C13: SPI_PREINIT CS
C14: FREE 
C15: MPU CS
D00: FREE 
D01: FREE 
D02: SDCARD 
D03: FREE 
D04: FREE 
D05: FREE 
D06: FREE 
D07: SPI1 MOSI
D08: FREE 
D09: FREE 
D10: PINIO1 OUT
D11: PINIO2 OUT
D12: FREE 
D13: FREE 
D14: FREE 
D15: FREE 
E00: FREE 
E01: FREE 
E02: SPI_PREINIT CS
E03: LED1 OUT
E04: LED2 OUT
E05: FREE 
E06: FREE 
E07: FREE 
E08: FREE 
E09: FREE 
E10: FREE 
E11: SPI_PREINIT CS
E12: FREE 
E13: FREE 
E14: FREE 
E15: FREE 

# 

@mmosca mmosca marked this pull request as draft August 30, 2023 22:19
@shota3527
Copy link
Contributor

shota3527 commented Aug 31, 2023

@shota3527 can this be a potential problem for the vtol mixer profiles?

@mmosca
I have viewed the code and the impact is minimal on mixer profile features.
mixer profile maps the TIM for all mixer_profile only once on the boot.

BTW I think there is a bug in the configurator.
If the only servo rule is on servo 3. Then servo 1-3 is mapped to s1-s3 in the firmware(servo count is 3), but the configurator will show servo3 is mapped to s1 only

@mmosca
Copy link
Collaborator Author

mmosca commented Aug 31, 2023

Setting all options as motor/servo causes issues with fw.

I will probably change the assignment order to give motors priority (like in multicopter mode)

Assign motors
Assign servos

@mmosca
Copy link
Collaborator Author

mmosca commented Aug 31, 2023

@shota3527 can this be a potential problem for the vtol mixer profiles?

@mmosca I have viewed the code and the impact is minimal on mixer profile features. mixer profile maps the TIM for all mixer_profile only once on the boot.

BTW I think there is a bug in the configurator. If the only servo rule is on servo 3. Then servo 1-3 is mapped to s1-s3 in the firmware(servo count is 3), but the configurator will show servo3 is mapped to s1 only

Good to know it won't be an issue wit VTOL. I would rather have that than this :)

I am still planning on doing some extra work on the assignments. I will check the behavior to make sure we follow the servo order when doing assignments

mmosca added 2 commits August 31, 2023 22:50
The stress test MATEKH743 target seems to handle things well.

If all outputs are both servo and motors,

It will go through outputs in order and claim all outputs in order, until the desired number of motors is achieved.
@mmosca mmosca added the Release Notes Add this when a PR needs to be mentioned in the release notes label Sep 1, 2023
You should be able to achieve the same result with this pull request,
hopefully before supporting overriding individual timer functions.
@stronnag
Copy link
Collaborator

stronnag commented Sep 1, 2023

I flashed this to a MATEKF405 tricopter
After arming:

  • Port motor does not run
  • Servo is not responsive to yaw.
mmix reset

mmix 0  1.000  0.000  1.333  0.000
mmix 1  1.000 -1.000 -0.667  0.000
mmix 2  1.000  1.000 -0.667  0.000

# Mixer: servo mixer
smix reset

smix 0 5 2 -100 0 -1

...

set platform_type = TRICOPTER
set model_preview_type = 1
set servo_pwm_rate = 330
set tri_unarmed_servo = OFF
...

It had previously been working (from INAV pre 1.0 to date ( and with MATEKF405 since .c May 2018))

@stronnag
Copy link
Collaborator

stronnag commented Sep 1, 2023

MATEKF405 Quad appears to work OK

@mmosca
Copy link
Collaborator Author

mmosca commented Sep 1, 2023

MATEKF405 Quad appears to work OK

And if you add a servo, will it land on s5 and second one on s6?

Probably s6. It may skip s5 because of led

@stronnag
Copy link
Collaborator

stronnag commented Sep 1, 2023

MATEKF405 Quad appears to work OK

And if you add a servo, will it land on s5 and second one on s6?

Probably s6. It may skip s5 because of led

I'll try that later. BTW, the tricopters (actually two of them) both have the servo on S1 (i.e. built prior to the later "S6" variant). And I'd really prefer not to have to dismantle them to change it ...

@mmosca mmosca mentioned this pull request Sep 1, 2023
@mmosca
Copy link
Collaborator Author

mmosca commented Sep 1, 2023

MATEKF405 Quad appears to work OK

And if you add a servo, will it land on s5 and second one on s6?
Probably s6. It may skip s5 because of led

I'll try that later. BTW, the tricopters (actually two of them) both have the servo on S1 (i.e. built prior to the later "S6" variant). And I'd really prefer not to have to dismantle them to change it ...

That is my main concern for deciding if I should change existing targets. Out of the box settings may shuffle the outputs of some targets.

I will add the possibility of forcing a timer to servos or motors, but the upgrade process may be painful.

@DzikuVx
Copy link
Member

DzikuVx commented Sep 1, 2023

@mmosca MatekF722 with following configuration skips S5 completely

image

Signal is not generated on S5, checked with the scope

output_mode sets default, inidividual timer is processed afterwards.
@mmosca
Copy link
Collaborator Author

mmosca commented Sep 1, 2023

Overriding individual timers is now working: timer_output_mode 2 MOTORS forces TIM3 to be a motor, and timer_output_mode timerId SERVOS forces it to servos.

Timer id is 0 based, so TIM1 is id 0

Currently, setting s1 timer to SERVO causes FW to have no motors.

@stronnag
Copy link
Collaborator

stronnag commented Sep 2, 2023

MATEKF405 Quad appears to work OK

And if you add a servo, will it land on s5 and second one on s6?

Probably s6. It may skip s5 because of led

It ends up on S6:

A08: SERVO5 OUT

@stronnag
Copy link
Collaborator

stronnag commented Sep 2, 2023

The legacy MATEKF405 tricopter steadfastly refuses to move the servo off S6 and to S1, with

timer_output_mode 3 SERVOS

I still end up with:

A08: SERVO4 OUT
C06: MOTOR1 OUT
C07: MOTOR2 OUT
C08: MOTOR3 OUT

Am I missing some magic step?

@mmosca
Copy link
Collaborator Author

mmosca commented Sep 2, 2023

FW now works when overriding first timer as servo, on MATEKH743. S1 and S2 get assigned to servos, S3-S6 as motors and S7+ ends up as servos.
image

timer_output_mode

timer_output_mode 0 AUTO
timer_output_mode 1 AUTO
timer_output_mode 2 SERVOS (s1 uses TIM3)
timer_output_mode 3 AUTO
timer_output_mode 4 AUTO
timer_output_mode 5 AUTO
timer_output_mode 6 AUTO
timer_output_mode 7 AUTO
timer_output_mode 8 AUTO
timer_output_mode 9 AUTO
timer_output_mode 10 AUTO
timer_output_mode 11 AUTO
timer_output_mode 12 AUTO
timer_output_mode 13 AUTO

@mmosca
Copy link
Collaborator Author

mmosca commented Sep 2, 2023

The legacy MATEKF405 tricopter steadfastly refuses to move the servo off S6 and to S1, with

timer_output_mode 3 SERVOS

I still end up with:

A08: SERVO4 OUT
C06: MOTOR1 OUT
C07: MOTOR2 OUT
C08: MOTOR3 OUT

Am I missing some magic step?

The timer id is 0 based.

Try:

timer_output_mode 2 SERVOS

It will probably be more obvious once I add the timer Id to the configurator :)

@stronnag
Copy link
Collaborator

stronnag commented Sep 2, 2023

The timer id is 0 based.
Try: timer_output_mode 2 SERVOS

We have a winner ...

C06: SERVO4 OUT
C07: MOTOR1 OUT
C08: MOTOR2 OUT
C09: MOTOR3 OUT

@stronnag
Copy link
Collaborator

stronnag commented Sep 2, 2023

Excellent, thank you.

@stronnag
Copy link
Collaborator

stronnag commented Sep 2, 2023

Once this is ready to merge, I'll update Cli.md (with example).


Note:

* `timer` identifies the timer **index** (from 0); thus is one less than the corresponding `TIMn` definition in a target's `target.c`.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should mention the timer index shown in the mixer tab of the configurator. Probably easier for the user and less error prone than opening the target.c file to find the timer mapping.

Also, at32 chips call the timers TMRn.

@mmosca
Copy link
Collaborator Author

mmosca commented Sep 5, 2023

After I validate the msp commands, this will be ready for review and merging.

I will probably save any further target changes to a separate pr to minimize the changes in this one. Not changing a target just means that you are more likely to need to manually override a timer.

The configurator without related changes should work fine, but won't display the timers or the options to override.

@mmosca mmosca added this to the 7.0 milestone Sep 5, 2023
@mmosca mmosca marked this pull request as ready for review September 6, 2023 17:06
@mmosca
Copy link
Collaborator Author

mmosca commented Sep 6, 2023

Just checked that the msp messages work, now, to make the configurator send the correct messages. :)

@mmosca
Copy link
Collaborator Author

mmosca commented Sep 8, 2023

Tested on at32, with corresponding configurator.

Last item should have been a servo, but I overrode the timer as motor.

first 4 items are already hadcoded as motors, since this is an AIO fc.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Release Notes Add this when a PR needs to be mentioned in the release notes Requires Configurator
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants