Queued trajectory operations

I’ve been using trajectory planning movements and they are awesome! But if I issue two set_position commands without delay between them, the first will not fully execute because the second immediately takes over. In order to implement a series of position commands that each fully complete, do I need to monitor the position and start the next command only after I observe the current command has completed?

If so, that is going to add tremendous overhead to Odrive’s controller (because of polling position) and the accuracy will be poor (in time, not position). It would seem an alternative would be to queue up commands in the controller and execute them serially since the controller has easy access to position and is already monitoring position to implement the plan.

Can someone comment on the preferred approach to serialized position commands? Thank you.

Cheers, Chris

Executing commands sequentially could be a real problem if you want to change the position now.

Two-edged sword.

That’s an excellent point, which is probably important for some applications. I imagine it’s important for safety where force feedback is being monitored and responded to. But that leaves my question open as “what is the preferred practice for minimizing latency between position changes?”. Is to monitor the position via polling? I can also imagine a callback mechanism that let’s the called known “has arrived at position”. I’m using the serial ASCII interface (also Odrivetool for experimenting) so I don’t know if there is a mechanism for “callbacks” since that would probably just mean bidrectional ASCII interface.

Either you poll the Odrive controller continuously or you calculate the expected time to complete the command on the microcomputer that is sending the commands.

I would consider the latter and use an interrupt timer. You can at least limit the number of times you need to poll the Odrive.

Alright, that sounds like a good approach. Thanks. I can look at the trajectory planning code and perhaps copy the algorithm to do predictive computation on the expected time. Then, I imagine I can remove a little time and start polling before the expected arrival time. This is still error prone since my total movement time might be around 0.1 seconds between new position settings. That will require polling at a maximum 0.05 second delay between polls.I think ultimately it would be best for the Odrive controller to send a “at(position)” when it’s finished but I haven’t understood the firmware well enough to make that change yet. Baby steps!

Essentially what we didn’t want to do was put a full GCODE parser / planner in the ODrive, that’s not really what it’s for. You can monitor the trajectory_done flag, but the drive will always come to a stop first which you may not want.

Your suggestion worked great; thank you. I do want to fully stop because I’m reversing direction after the first move. This “move” function rotates back some turns, then rotates forward to zero. It’s not robust, but shows the monitoring of the flag. I experimented with finding the exact time of the trajectory and polling doesn’t slow it down within my tolerances. Because the movement is rapid, the polling interval is short but as I said it doesn’t seem to impact the Odrive controller.

def traj_move(pos):
          current_pos = odrv0.axis0.controller.input_pos
          reduction = 6.0
          odrv0.axis0.controller.input_pos = current_pos - pos * reduction
          time.sleep(0.15) # don't SPAM controller while it's doing most of the work
          while (odrv0.axis0.controller.trajectory_done == False):
              time.sleep(0.05)
          odrv0.axis0.controller.input_pos = current_pos

traj_move(0.25) # 90 degree rotation

On the other hand, some applications really want to know that the machine has reached the position and is ready for next stage of the operation. A notification about the flag rising would be desirable.

I’m still a novice with this tool; I don’t see any “notifications”. It appears to me so far that the Odrive controller never sends a message unless it had a query. So, an asynch message arriving to the host would be surprising and certainly jam up communications. But maybe if the host requested a message and then was setup to handle the response, that would be okay. You wouldn’t want to pause the transmission and reception of other messages in the meantime, though. So, maybe adding a message id could help. This is speculation on my part. I’m still looking at the controller sources and don’t know jack yet.

You can set up periodic messages on CAN with the CANSimple protocol, in an upcoming version one of the available cyclical messages has the trajectory done flag.
cc @Wetmelon