How to make motor turns to set position

Hi All,
I am new with odrive and try to control the position of the motor.
I want to turn the motor to turn until it gets the set position.
Try to use …controller.pos_setpoint and got error “this attribute cannot be written to”.
If I use the encoder position then how to make the motor move to the encoder position?

Thanks for your help

Hi there,

you have to use input_pos, not pos_setpoint

Are you using odrivetool? If you type odrv0.axis0.controller. and then hit tab, it will show you everything you can use, this can be handy if you are a beginner.

Thanks Acisre. Yes I am a beginner and using Odrive.
Is it a good idea to set current_lim to zero to stop the motor when it reaches the position?
I did that but don’t know is it a good idea to do that or do we have any command to stop the motor?
Went through the Docs but didn’t see any or maybe I missed :slight_smile:

hmm no you should not do that.

I think you are a bit confused. If you set your controller in position control mode, and you set a certain input_pos, then your motor will go to that input position and it will stay there, until you give another input_pos and so on…

What exactly are you trying to do?

Let say I have point A and I want to move to point B but I don’t know where is point B yet. So we can not use controller.input_pos = “A number”. I want to program so that I can use a joystick or press and hold a key on keyboard to make the motor keeps moving until it reaches point B then I will stop the movement by releasing the key or joystick. Record the point B position (encoder.shadow_count) and store it. And keep doing that until the set up is done. I will have a set of data of all positions.
When the operator runs the program, the motor moves in point B and stop there for a while do some tasks and move to the point C and stop, do some tasks and so on…
And the accuracy +/- 0.005 inch.
That is what I am trying to do. And I am using raspberry and Python.
To do that there will be three buttons MOVE, STOP and SAVE on the setup screen. Press the MOVE button motor will move. Press the STOP button, motor will stop. Press SAVE, the position will be saved.

I think you should create some kind of state machine

while button left pressed
{
input_pos = input_pos - small increment
wait untill pos_estimate = input_pos // to prevent the loop from executing too fast
}

while button right pressed
{
input_pos = input_pos + small increment
wait untill pos_estimate = input_pos // to prevent this loop from executing too fast
}

if button save pressed
{
read pos_estimate
add this value to some array
}

but perhaps there are better ways…

You could use velocity mode for ‘running’, and then when you want to stop at a particular position, you can switch to position mode just before you get there.

I think velocity mode will work as my goal. I will try it today.
If I have a position 252568 (read encoder) do we have command to move the motor to that number directly of we have to use while loop and if command?
I wish we have some thing like: .controller.input_pos(252568) :slight_smile:
Or do we have any configuration to do that?
Thanks for reading my questions.

Tried the velocity control mode and it is what I want. The motor turns clockwise but when I switch to position mode then the motor turn counterclockwise 2 turns and stop.
Any ideas of configuration?
Thanks

Try something like:

# run at given speed
def run(axis, vel):  
   axis.input_vel = vel
   axis.controller.control_mode = CONTROL_MODE_VELOCITY_CONTROL

# stop at the position that we would be in a given amount of time (time should be fairly short as this will race towards the stop point)
def stop (axis, time):
   stop_pos  = time * axis.encoder.vel_estimate + axis.encoder.pos_estimate
   axis.input_pos = stop_pos
   axis.controller.control_mode = CONTROL_MODE_POSITION_CONTROL

import time

ax0  = odrv0.axis0
run(ax0, 5)
time.sleep(1)
stop(ax0, 0.2)

Thank you Towen. Will try.
How fix the error:
MOTOR_ERROR_UNKNOWN_TORQUE
MOTOR_ERROR_UNKNOWN_VOLTAGE_COMMAND
I have 2 motors but the axis0 always get those errors if I turn it small increment. The axis1 is fine.

Are you using the ferrite rings? They help a lot with these kind of errors.

No, I don’t use it.
Let me look at it but the question is why axis0 or motor 0 get the errors…

I try the program and it works good. When I stop, the motor stops but it keeps moving a little bit back and fort (about 0.1 turn) and not stop completely. I have to reboot Odrive.
If I use axis.controller.input_vel = 0 to stop the motor then it stops completely

Hm interesting, it may be that input_vel is still active in position mode as a feedforward term.

Try putting axis.controller.input_vel=0 in the stop function.

Yes that what I did. And it stop completely.
Now just learn how to do a tuning so that I can get it stop at the tolerance. If you have an example of how to do a tuning please share. Actually I went through the Doc but still not know where to start :frowning:
Thanks

If it’s just a case of improving the accuracy of where it stops (but you don’t care if it takes a little longer to stop) then you could increase vel_integrator_gain - if this causes it to oscillate, then halve pos_gain.

If you still get vibration, you can try reducing motor.config.current_control_bandwidth
Also the ferrite rings will help with that too.

Hello Towen,
This command: start_liveplotter(lambda:[odrv0.axis0.encoder.pos_estimate, odrv0.axis0.controller.pos_setpoint]) How to use it in VS code?
I want to see the overshoot during tuning process.

Thanks

The easiest way is to edit the odrivetool script and change the liveplotter section to use the signals you want, and then use odrivetool liveplotter