For my project I need to control both motors using the PWM outputs of my RC reciever.
I set everything up and it works, except the motors don’t brake when I have the stick in the middle position.
The promlem I encouter is that vel_setpoint never gets 0.0, it floats always around [-1000, 1000], because my reciever doesnt produce a perfect 1500ns in middle position!
Is it possible to have an interval e.g. 1450ns-1550ns, where vel_setpoint gets set to 0.0?
Or can I do something similar to get the motors to brake at 0-position?
So I had time and I tried to program something. It’s untested, but I think it works. Here is what I did:
First of all, I added a new variable in the board_config that lets you set a limiter.
struct PWMMappingLimiter_t {
float min = 0;
float value = 0;
float max = 0;
};
PWMMappingLimiter_t pwm_mappings_limiter[GPIO_COUNT];
Adding it to board_config has the effect that the values get saved by calling odrvX.save_configuration().
The pwm_mappings_limiter variable gives you the option to set a minimal and a maximal pwm boundary (in %) and a limiting value (also in %) where the received pwm value will be limited to when the original pwm value lies between the minimal and maximal boundary. The code for clarity:
If the pwm then changes in [0.47; 0.53], then the pwm value will be limited to 0.5 and as a result will set the vel_setpoint to 0.
You can see the source code here: https://github.com/LowiekVDS/ODrive.
In ODrive/Firmware you will find two precompiled pwminterval_xxV.hex files, one for the 48V version and one for the 24V version, both ODrive V3.5.
I finally found the time to test your code.
Thank you for the time you spent writing it!
The code works really well, its easy and fast, however I found some issues/improvements:
If fraction jumps out of the limiter.min/limiter.max intervall, there is no smooth transition - the motor makes a jump to a certain speed. The effect is especially strong if you have a big limiter intervall.
The limiter.value parameter schould not set the fraction, but the direct value it outputs to e.g. to vel_setpoint with odrv0.config.gpio3_pwm_mapping.endpoint = odrv0.axis0.controller._remote_attributes['vel_setpoint'], when the pwm signal is inside the limiter interval. For my example this would be zero.
Otherwise, when you have an asymmetrical mapping.min/mapping.max interval, its hard to hit exactly 0 on the output, just by setting the fraction inbetween.
I would really appreciate it if you find the time to adjust the code!
Thank you in advance
Hi, I’m having the same issue. I can’t find the pwm_mapping_limiter. Is it available only in the custom firmware? Could we have this baked into the standard firmware please? Thank you.
Most remote controls will not be able to return to exactly the middle due to mechanical tolerances as well as a whole range of reason. This function would be very helpful for an integrated odrive solution.
What I did was program a curve in the remote, so it emits “0” (or 1500, if you want), from 3% before untill 3% after the midpoint, thus creating a deadband zone. Works pretty well.
I solved this issue with a custom firmware, where I also implemented my suggested improvements.
I am on holiday right now, but I will upload the files later this week!
Hi, my custom firmware was based of an old version, back than i did not even use git.
I recreated my edits with the newest firmware version in a new fork:https://github.com/felhub/ODrive
I can make you a .hex file for your ODrive version if you want.
But currently the firmware is untested, because I have some other trouble with my ODrive not calibrating (even with unmodified firmware)
I will report back when I tested the new firmware and write a little documentation on how to use the gpioN_pwm_mapping_zero feature.
EDIT: I marked all edits in the code with felhub - tracker so you can easily find what I canged.