I’m using an Arduino Mega to control 3x v3.6 Odrive boards over UART for a skidsteer vehicle. I want to be able to accelerate from a stop, turn by reducing/increasing power to one side of the vehicle, and then decelerate to a stop using regenerative braking. How I currently do this is in closed loop velocity control mode via the OdriveArduino library, aka. “odrv0.setVelocity(0);”
The problem is that this causes the motor to actively try to reduce its velocity to the set value, effectively causing braking while trying to turn and significantly reducing total power/forward speed. Also, when braking the vehicle, it comes to a stop and then moves backward because inertia carries it past the position where Odrive thinks it was supposed to stop. Is there a way to disable that feature of trying to hold position at 0 velocity? I’d rather it just resist movement than actively try to spin back to where it was before.
Also during normal deceleration (aka throttle is reduced but brake is not engaged), the motors should decelerate to the new velocity without braking. Then if the speed drops too far, the motors should attempt to maintain the set velocity, but should not resist overspeeding (aka, moving down a hill). How can I implement this type of control?
TLDR; Velocity control works as advertised, but it isn’t suitable for controlling my vehicle application. Are there alternatives? How can those be implemented with Arduino via UART?
Thanks in advance and apologies if I haven’t used the correct terminology, I hope you can parse together what I am trying to say.
The ODrive won’t necessarily try to hold position in velocity control - you may be seeing the integrator gains being tuned incorrectly.
When in closed loop velocity control, the ODrive will accelerate or decelerate the motor to try to achieve the specified setpoint. In cases where you want to disallow braking, you can set torque_soft_min to zero.
You may also want to consider using the ODrive in torque control mode from the Arduino - if you vary the input torque based on the required characteristics (braking / coasting / etc), you should be able to meet the requirements. You could alternatively dynamically control the torque_soft_min.
Hi thanks for the response. How do I disable the position holding feature in velocity control? What happens now is if velocity is set to 0 and then I spin the motor by hand, it resists the rotation but then rotates back in the other direction when released until it is in the position where it started.
Is there an existing arduino library for torque control mode? If I understand correctly, torque control would essentially control the current sent to motors which is exactly what I need. The only concern I have in that case is how do you control the speed of the vehicle? The velocity feedback to the Arduino in the example library doesn’t seem to be very accurate and also cannot be polled very quickly due to the UART connection.
Would this not also impact the controllers ability to control the motors effectively? I do still have some tuning to do on the PID because it overshoots a little on acceleration causing minor low frequency oscillation, so I will try it. But I don’t understand how disabling the integrator term would change anything with regard to the “position holding”.
Unless I don’t understand how the backend works, I’ve found the documentation to be somewhat lacking in terms of explaining how the system works and how to set it up. I’ve had nothing but errors trying to get these drives to work, and now I find they may not even be capable of operating in a mode which works for my application. I wish the documentation was more thorough and the community had more examples. This is all that I’ve found to describe the “vel_gain_integrator” setting:
The problem is that the integral of velocity is the position, so if you control that, you automatically hold position.
If you cannot get the controller stable without the integrator gain, you might wanna try to limit controller.vel_integrator_torque. There is no such feature built in, but you can add it yourself if you use V3. Or you can just check its value yourself periodically and lower it if it gets too high.