ROS Resources: Documentation | Support | Discussion Forum | Service Status | Q&A answers.ros.org

Msg type for publishing JointCommands

It has been bugging me for a while that I can’t seem to find something like sensor_msgs/msg/JointState.msg, but for commanding positions for multiple joints to move immediately.

ros-control seems to be looking for a replacement for their msg type used for their ForwardCommandController, due to Float64MultiArray being deprecated as of Foxy, and a semantically meaningful message type is recommended.

Some discussion has taken place in ROS Answers: Msg type for publishing JointCommands? and this topic continues off that. @gavanderhoorn

Perhaps, we could have a new msg type JointCommand.msg

string[] names
float64[] positions
float64[] velocities
float64[] accelerations
float64[] effort

Or, a msg type like

uint8 TYPE_POSITION=0
uint8 TYPE_VELOCITY=1
uint8 TYPE_ACCELERATION=2
uint8 TYPE_EFFORT=3

uint8 type
string[] names
float64[] values

Otherwise, we could have four separate msgs for each type of actuator, JointPositionCommand.msg, JointVelocityCommand.msg, JointAccelerationCommand.msg and JointEffortCommand.msg.

It would be nice to add this to control_msgs or common_interfaces. What do we think?

I was wondering if we could pull off something akin to this: control_msgs/DynamicJointState.msg at galactic-devel · ros-controls/control_msgs · GitHub but as a command type. With ros2_control we wanted to break away from the quartet of position, velocity, acceleration, effort and allow people to use whatever they want. Of course these would probably account for 90% of commands still so I’m wondering what’d be the best approach for this.

I’d definitely not want to see a message explosion with JointPositionCommand and friends.

2 Likes

I’m still wondering (as I did with DynamicJointState) whether there would be a solution where we don’t introduce separate types for each control interface (or use strings to describe which of them is contained in a union-type msg), but instead take a slightly more generic approach and use float64 (and arrays/lists of those) where appropriate (or other types, it’s not limited to reals).

That would make composition easier, scale well, would be similar to other modular/MBE control frameworks (Simulink comes to mind, or Labview) and would avoid the “message explosion” @bmagyar refers to.

A message which is essentially the union of all possibilities is also something which I’m personally not a fan of. I like the clear semantics conveyed by a message type. That is opposite to what I just wrote, I know, but that’s why I’m not proposing something which would be a solution: I haven’t yet been able to reconcile my two ‘requirements’.

2 Likes

Maybe trying something like:

string[] joints
string[] param_types
value_array[] value_arrays
value_array:
float64[] values

Where joints would list the joints (and their order) contained in the message, param_types would list the types of parameters (and their order) for each joint, and value_arrays would contain an array for each joint with the values as described by param_types.

Example:

["joint1", "joint2", ...]
["position", "velocity", ...]
[ [joint1_pos, joint1_vel, ...], [joint2_pos, joint2_vel, ...], ...]

This prevents param_type different joint-to-joint (and duplication of redundant information), while still keeping value_type generic and future proof.

Isn’t that basically what DynamicJointState does? @bmagyar @destogl ?

@BenArtes, @gavanderhoorn is right, control_msg/DynamicJointStates does exactly that in a bit different format:

# List of resource names, e.g. ["arm_joint_1", "arm_joint_2", "gripper_joint"]
string[] joint_names
# Key-value pairs representing interfaces and their corresponding values for each joint listed in `joint_names`
# Interface names are for example: "position", "velocity", "temperature", "my-cool-interface", "whatever", ...
InterfaceValue[] interface_values
        string[] interface_names
        float64[] values

Oops, I unintentionally skipped over @bmagyar 's message when reading this for the second time and missed the reference to DynamicJointStates.

The only difference is that DynamicJointStates duplicates the interface_names and thus allows them to be different between joints in a message. This makes it more general, but increases message size, misuse potential, and parsing complexity / error handling (though implementation / convention could require they be the same if required).

I wasn’t aware of control_msgs/DynamicJointState.msg. Doing something akin for commanding joints would be a perfect fit for what I’m trying to achieve.

The new msg, let’s call it DynamicJointCommand.msg for now, would be almost identical to DynamicJointState.msg as below. Perhaps the header doesn’t quite make sense for this msg.

# DOES A TIMESTAMP OR FRAME MAKE SENSE?
std_msgs/Header header

# List of resource names, e.g. ["arm_joint_1", "arm_joint_2", "gripper_joint"]
string[] joint_names
# Key-value pairs representing interfaces and their corresponding values for each joint listed in `joint_names`
InterfaceValue[] interface_values

Considering the new msg type DynamicJointCommand.msg is almost identical to DynamicJointState.msg, maybe we could rename DynamicJointState to something that can be used for both commands and states.

I would like it better if had a arm index too, like…
[“arm_1_joint_1”, “arm_1_joint_2”, “arm_1_gripper_joint”]
some of us are working with 2 arms, or four legs.

@BenArtes

The only difference is that DynamicJointStates duplicates the interface_names and thus allows them to be different between joints in a message. This makes it more general, but increases message size, misuse potential, and parsing complexity / error handling (though implementation / convention could require they be the same if required).

Very valid comment. Do you have an idea how to address this issues? The message you proposed is basically (a bit more flexible) JointState Message, where all the joints have the same interfaces. DynamicJointState tries to address cases where not all joins have the same interfaces, I.e. some I them can have unique, totally unrelated interfaces. Any proposal to make it better is very welcome :slight_smile:

DynamicJointState to something that can be used for both commands and states.

@Kenji_Brameld very Good idea. Do you have a proposal? Maybe „DynamicJointValues“? (maybe too ambiguous)

I would like it better if had a arm index too, like…
[“arm_1_joint_1”, “arm_1_joint_2”, “arm_1_gripper_joint”]
some of us are working with 2 arms, or four legs.

@Kajack You are free to add your joint names like that. That is actually recommended use in ros2_control. Exactly this is a reason why we have „${prefix}“ variable in front of all Joint names in example xacro files in ros2_control_demo repositories. :smiley:

I think it could also make sense to just use the existing “DynamicJointState” msg name to command joints, as we’re trying to reach a certain state for the joints. Just looked up the definition of the word “state”, and it came up as the particular condition that someone or something is in at a specific time, so the definition doesn’t seem to be tied to “observing” a state.

However, as you suggested, “DynamicJointValues” I think is also good, and makes sense.

Something that is confusing, is the word “Dynamic”. “DynamicJointState”, sounds like JointStates that change with time. But really, it means JointState that is dynamic and flexible to fit any type or number of joints, and I’m gonna guess you used the word “Dynamic”, to distinguish it from the pre-existing “JointState” msg.

If we go with “DynamicJointValues”, maybe we could drop the “Dynamic”, and just have “JointValues.msg”.

1 Like

Something that is confusing, is the word “Dynamic”.

That exact discussion we had when message was introduced.

The best place to continue this discusscuss is control WG meeting. It is this Wednesday. @bmagyar announces it usually on Monday with a link to the agenda document. Please add a discussion point there.

@destogl Sounds good, although the timezone makes it difficult (2.00am Japan time), I’ll try and make it on for at least this week’s.

We used to alternate the timeslot between the Americas-friendly and an Asia-friendly one but attendance was non-existent after a while so opted for the first. If there’s interest we could bring the rotation back!

1 Like