ros_canopen icon indicating copy to clipboard operation
ros_canopen copied to clipboard

Make homing callable

Open mathias-luedtke opened this issue 7 years ago • 7 comments

  • Implement option to turn off homing at init
  • Provide function to trigger the homing individually:
    1. Stop ros_control
    2. trigger homing for selected joints in parallel
    3. restart control loop

mathias-luedtke avatar Mar 17 '17 12:03 mathias-luedtke

What about creating a new controller for the purpose of Homing? That way the stop / start of ros_control would be taken care of.

The issue would be which hardware_interface to use; I was tempted to to use hardware_interface::VelocityJointInterface as the HomingMode CAN OD Entries specify speed, but there is a limited channel of information (double vel) that isn't really suitable for sending start / stop.

I'm still open to the above, but it might be worthwhile to consider creating a new hardware_interface with a different datatype at its core, either bool for start_motion, or some kind of uint / enum for sending specific commands.

Errors / state during homing could still be received through the JointStateInterface / Diagnostics.

BenArtes avatar Oct 29 '19 22:10 BenArtes

What about creating a new controller for the purpose of Homing?

I would not mix these concepts. Controllers are meant to be switchable, but homing is a one-off process.

mathias-luedtke avatar Nov 04 '19 09:11 mathias-luedtke

What about creating a new controller for the purpose of Homing?

I would not mix these concepts. Controllers are meant to be switchable, but homing is a one-off process.

hm.

What about systems with relative encoders? I could see those needing to be re-homed after an e-stop or some other error (like a hw crash).

gavanderhoorn avatar Nov 04 '19 09:11 gavanderhoorn

What about systems with relative encoders? I could see those needing to be re-homed after an e-stop or some other error (like a hw crash).

That's exactly the target use case for this issue :) If we would expose Homing as a ros_control controller, it could get mixed with other modes (in a chain) freely and we would need to implement cancellation etc The current homing implementation ensures a defined order of operation.

mathias-luedtke avatar Nov 04 '19 10:11 mathias-luedtke

So you're imagining an additional rosservice (driver/home) that accepts a list of joints to home, stops associated controllers, homes, then restarts the associated controllers?

BenArtes avatar Nov 04 '19 16:11 BenArtes

After looking into this a bit I still believe that creating a new controller is a more flexible way to implement this behavior. In our robot there are edge cases that could be caused by a malfunction that we would need to recover from by re-homing. For this we'd need to leave portions of the robot active and still controlled by ros_control while homing the affected joints.

It also seems that you're suggesting shutting off ros_control and Homing all home-able joints at once, which in our robot is also an issue as the design has parts colliding in the all joints homed position. By implementing homing as a controller we can home a subset of joints, adjust position, then home the remaining joints.

Halting / Cancellation are all capabilities described in DS402's Homing.

BenArtes avatar Dec 04 '19 20:12 BenArtes

Summary of Work so far

I implemented a controller based version of executable homing and it was less than ideal. We use ros_canopen and gazebo_ros_pkgs to control a robot and simulate a robot. While I got an implementation that worked quite well for the robot, I ran into issues that would have required me to implement fake transmissions to get the controllers to work with gazebo_ros_pkgs.

I think there is value in potentially having a ros_control HandleType that can pass a bool and/or uint enum for passing non-numerical command values, but I imagine that would be a contentious feature. If that existed this would have been straight-forward and worked quite well. As it stands, blocking this feature until that gets implemented isn't a good idea.

Below are some issues I ran into for posterity:

  • Had to create an entire new set of controllers / handles + grouped versions to pass a bool cmd message to start / stop homing; this caused a lot of code duplication across ros_canopen, ros_control, and ros_controllers.
  • The new controllers / handles caused friction inside the ros_canopen codebase; an example there are numerous places where JointHandle is the assumed Handle (CommandMap, handleWrite etc). This will need to be dealt with in some way to support modes with more than one command (PosVel, PosVelAcc). I temporarily implemented it by function overloads on setTarget etc, directly storing the current mode then hard-coding the calls to the correct setTarget based on the mode. Don't think it was ideal.
  • gazebo_ros_pkgs/gazebo_ros_control uses Transmissions for declaring interfaces, because there isn't an interface for the new controllers / handles it wouldn't work until those are implemented.

Going forward:

Because of our robot I still wish to find a solution that supports keeping ros_control running for non-homing or non-associated joints.

The obvious solution is a service, but:

  • Without hacking together an async version of a service callback it will block the thread
  • It cannot be preempted (though I suppose it could be stopped out of band with e-stop / quick-stop)
  • I believe homing to be pretty typically a 'long-running' service

So I'm currently leaning toward an ActionServer.

BenArtes avatar Dec 12 '19 18:12 BenArtes