-
Notifications
You must be signed in to change notification settings - Fork 13.7k
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
[Sponsored by ARK] Bidirectional DShot #23863
base: main
Are you sure you want to change the base?
Conversation
e4681c4
to
16dc6d4
Compare
This pull request has been mentioned on Discussion Forum for PX4, Pixhawk, QGroundControl, MAVSDK, MAVLink. There might be relevant details there: |
Thanks for your work @dakejahl. I'll review and test this on the Holybro 6Xs as well as Cubes tomorrow. |
Do I remember it right that I did the capture round robin style, so one channel per output pulse. Is that what you mean with this? And so if I understand you right, we need 4 DMA channels to enable this? Which means that we need to disable DMA for serial ports or sensors to enable this, right? And what are the steps to enable this? It's not on by default, right? |
@julianoes your impl was doing round robin using a single DMA and reading from the burst register. You were re-using the 1 DMA from the burst output for the input capture.
The init logic determines if DMA is available for each channel, so this will work with only 1 DMA (the 1 used for burst output anyway). If there are more DMA available, then great, but they are not strictly required as the channel will be marked in the
DSHOT_BIDIR_EN parameter enables this, it is disabled by default |
Aha! So then you only have feedback for part of the ESCs essentially?
Thanks, of course! 🤦♂️ |
yes exactly, you'd only have feedback from 1. This leads me to a question I have: is there a notch filter per ESC when using the gyro dynamic notch filter? (IMU_GYRO_DNF_EN). We could support round robin for the 1 - 3 DMA use case. |
That's what I'm thinking, but I'm not aware how the dynamic notch filtering works. |
I bet @dagar or @bresch knows. Is there a notch filter applied for each ESC? Is it worth it to round robin the ESC RPM if we don't have 4 DMA available? It would be pretty easy to update the logic to round robin with the available DMA: 1 DMA: each channel is captured on every 4th measurement --> C x x x C x x x C x x x C ... |
Could you please provide me with some advice on how to solve this? @dakejahl |
@jgw365 I'm sorry but I really can't help you with a backport. Please test the PR as it is, and let me know if works on the fmu-v6c or not and we can go from there. |
Okay, thank you a lot. I cloned your commit in the branch 'dev/bidirectional_dshot_single_timer' and used the command 'make px4_fmu-v6c upload' to upload it to my drone. After plugging in a battery, it seems that the channels are not connected correctly, but the motor output is functioning properly by the actuator test in QGroundControl (QGC). |
A few weeks ago, I used julianoes‘ code from the branch 'pr-bidirectional-dshot'. I was able to achieve normal DShot ERPM; however, I noticed that there were many spikes caused by CRC errors, with a rate of about 10%. |
@jgw365 it looks like it does indeed work. The fmu-v6x only has 2 DMA channels available so it's only capturing the eRPM from the first 2 channels. Please read the above comments discussing this. I might end up implementing round-robin for the less than 4 DMA cases such as this. |
Got it, thank you very much! Looking forward to seeing your progress in development. |
@jgw365 can you test again? I pushed a commit which fixes a bug I introduced when trying to fix the F1 compilation |
Alright I've implemented and tested round robin @julianoes |
Co-authored-by: Julian Oes <julian@oes.ch>
This pull request has been mentioned on Discussion Forum for PX4, Pixhawk, QGroundControl, MAVSDK, MAVLink. There might be relevant details there: |
@hamishwillee I'm planning to try to make this work for 4 outputs for the Kakutes. |
This pull request has been mentioned on Discussion Forum for PX4, Pixhawk, QGroundControl, MAVSDK, MAVLink. There might be relevant details there: |
This pull request has been mentioned on Discussion Forum for PX4, Pixhawk, QGroundControl, MAVSDK, MAVLink. There might be relevant details there: |
Hi julianoes, I would like to test 6d1c183 on pixhawkv6x. However, I could not even build the firewire which reports error on flash size: s/libxx/libxx.a NuttX/nuttx/drivers/libdrivers.a NuttX/nuttx/libs/libc/libc.a NuttX/nuttx/drivers/libdrivers.a NuttX/nuttx/libs/libc/libc.a NuttX/nuttx/sched/libsched.a -lm -lgcc && :
Memory region Used Size Region Size %age Used
ITCM_RAM: 0 GB 64 KB 0.00%
FLASH: 1968072 B 1920 KB 100.10%
DTCM1_RAM: 0 GB 64 KB 0.00%
DTCM2_RAM: 0 GB 64 KB 0.00%
AXI_SRAM: 100860 B 512 KB 19.24%
SRAM1: 0 GB 128 KB 0.00%
SRAM2: 0 GB 128 KB 0.00%
SRAM3: 0 GB 32 KB 0.00%
SRAM4: 2 KB 64 KB 3.12%
BKPRAM: 0 GB 4 KB 0.00/opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/bin/ld: px4_fmu-v6x_default.elf section `.data' will not fit in region `FLASH'
/opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/bin/ld: region `FLASH' overflowed by 1992 bytes
collect2: error: ld returned 1 exit status
%
ninja: build stopped: subcommand failed.
make: *** [Makefile:227: px4_fmu-v6x_default] Error 1
Did I miss anything? |
We should get this in as is and add multi-timer support once myself or Julian finds time |
Thank you, and thanks to Julian as well! We would greatly appreciate the opportunity to use bidirectional DShot in our research. Looking forward to it! |
Everything looks good for a Pixhawk 6C. I checked that the RPMs were in the log file as well. Just a note about the logs I have the motors spin when armed. https://review.px4.io/plot_app?log=0df2557f-0bf0-4bb1-bc1b-a0435d0fc055 |
This pull request has been mentioned on Discussion Forum for PX4, Pixhawk, QGroundControl, MAVSDK, MAVLink. There might be relevant details there: |
I'm working with a hexarotor controlled by a Pixhawk 6C mini. Currently, I'm using Ardupilot to obtain the motor RPM, but would rather use PX4 if possible. Is this branch intended to work on a vehicle with more than four motors? I couldn't quite follow what was happening when there were varying numbers of DMA channels and timers, so I don't know what to expect if I run this branch. |
@yzgarrard It only works on the first timer. If you take a look at the fmu-v6x/src/timer_config.cpp you will see the first is Timer1 and maps to the first 4 motor channels. So only motors 1 - 4 will work with bidir dshot. |
@dakejahl So does it have solution to set more timer for BDShot ? [6,8 motors] |
This pull request has been mentioned on Discussion Forum for PX4, Pixhawk, QGroundControl, MAVSDK, MAVLink. There might be relevant details there: |
We discussed this on the Jan 22 call, we want to get this in, and will be looking into the best way to do it. |
|
||
esc_status.timestamp = hrt_absolute_time(); | ||
esc_status.counter = _esc_status_counter++; | ||
esc_status.esc_connectiontype = esc_status_s::ESC_CONNECTION_TYPE_DSHOT; | ||
esc_status.esc_armed_flags = _outputs_on; | ||
|
||
// We wait until all are ready. | ||
if (up_bdshot_num_erpm_ready() < _num_motors) { |
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.
On the IMXRT in an ideal case we receive from all motors the RPM.
If we miss the RPM from a single motor we still want to publish.
This if guard would stop that, but for logging you want to know this.
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.
Can you check the last commit? It should allow this check to always pass
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.
Let's merge it as is.
I don't have to time to test on real hardware, but I doubt will regress.
@dk7xe you've got time to test main when this pr is in?
The KakuteF7 flash is overflowing. @julianoes can we free up some flash on this board? |
First of all a big thank you to @julianoes for the initial implementation. This implementation differs in that it uses up to 4 DMA channels for Capture Compare input on all 4 channels of the first timer. The limitation to a single timer is due to the limited available DMA channels on most boards (4 without PX4IO on ARKV6X) This will work down to 1 DMA channel by only capturing the input from a single timer channel.
Implementation
If Bidirectional DShot is not enabled the implementation is the same as it was before. Timers will be configured for DShot mode if the timer supports Burst Mode and if there is enough DMA channels available (1 DMA per timer). If Bidirectional Dshot is enabled, only the first timer will be configured for DShot due to DMA channel limitations. Burst mode uses 1 DMA, and CaptureCompare mode uses 4 (re-using the DMA used during Burst). An hrt callback is used to process the eRPM frames since DShot frames have predictable timing but unpredictable pulse count. This webpage was a useful resource.
Further discussion
Initially I wanted to support bidirectional dshot on all timers with DMA simultaneously. This requires triggering each timer (burst/captcomp) sequentially so that we can reuse the available DMA channels between the timers.
Timer1 Burst (1DMA) --> Timer1 CaptComp (x4 DMA) --> Timer2 Burst (1 DMA) --> Timer2 CaptComp (x4 DMA)
I made it pretty far with this implementation but decide to scrap it because I kept running into race conditions and this development has already taken quite some time. I think it is still possible to do, but is out of scope of this PR. The code is structured in a way that should allow fairly easy extensibility to support this in the future.
Issues
An issue I found but am not fixing here is that DShot.cpp configures all of the channels on timers that have DShot enabled. This results in a pulse train on every channel output on that timer, regardless of if the output function is enabled. The fix is not super easy as it requires extra logic in order to properly initialize the timer channels for burst mode, since the enabled outputs need to be sequential. This is the current implementations behavior so I am leaving it as I found it.
Targets Tested
ARKV6X with 4 DMA channels
ARKV6X with 2 DMA channels
CubeOrange with 4 DMA channels
Screenshots

