ros-controls / ros_control

Generic and simple controls framework for ROS
http://wiki.ros.org/ros_control
BSD 3-Clause "New" or "Revised" License
475 stars 307 forks source link

How to propagate actuator commands from actuator to joint space #275

Closed jlack1987 closed 7 years ago

jlack1987 commented 7 years ago

I'm working in on the kinetic-devel branch, and need to have the transmissions propagate actuator commands from actuator to joint space, but am having trouble figuring out how to make this happen because no ActuatorToJoint interfaces are created when the transmissions are created. I know this is not typically something you need to do, but humor me.

I'm trying to do all of this without copy/pasting/modifying all of the work done by the transmission_interface_loader. I feel like there's gotta be a "built in" way to make this happen, but i'm struggling to see it. Any advice?

jlack1987 commented 7 years ago

The avenue I see that might be the way to go is to create my own RequisiteProvider implementations and in my implementation of the registerTransmission method i'll register the ActuatorToJoint_*_Cmd interface along with the jnt_to_act_cmd interface that already gets registered so I can go both ways with it. Thoughts?

bmagyar commented 7 years ago

So if I get the question right: you'd like to start a flow of information in the opposite direction? Is this about encoder feedback?

Could you sketch it up with draw.io or a small snippet of code?

jlack1987 commented 7 years ago

Yeah you got it. I want to be able to go in the opposite direction. It's not about encoder feedback. We will be using it as a way of making the simulation look like an actual piece of hardware.

So picture a SimRobotHw in a gazebo plugin that will read joint state information from the sim robot, convert to actuator space, then give that to another HardwareRobotHw implementation that converts that actuator state info to joint state info in the read() method. Then in the write() method, it'll convert any joint commands to actuator commands and send it back over to the SimRobotHw. So now the SimRobotHw has a bunch of actuator commands it needs to convert back into joint space so it can send those commands to the simulated robots joints.

Edit: This kinda looks like,

class SimRobotHw : public RobotHw
{
    read()
   {
       sim_jnts_to_ros_control_jnts();
       propegate_jnt_state_to_act_state();
       publish(); // publish actuator data to be received by HardwareRobotHw in its read() method
   }

    write()
   {
       subscribe(); // Receive actuator commands from HardwareRobotHw in its write() method
       propegate_joint_cmd_to_act_cmd();
       ros_cntrl_joints_to_sim_jnts();
   }

}

Then the other side looks like a typical implementation of a RobotHw as you would expect and doesn't do any reverse propegation.

jlack1987 commented 7 years ago

Ok I can confirm that creating my own BiDirectionalEffortJointInterfaceProvider that extends JointStateInterfaceProvider did the trick. In this new provider in the registerTransmission call I have it register the reverse interfaces which allows me to propegate information in both directions at will. I made similar interface providers for position/velocity as well. There were a few minor issues with the TransmissionInterfaceLoader that prevented this from working out of the box, and I have submitted a pull request to remedy those.

jlack1987 commented 7 years ago

Fixed in #276