# Publishing joint_state with python and displaying in rviz

Hey Guys,

I'm have a robot arm I'm trying to put into ros. I went through the urdf_tutorial and got a urdf that works with the tutorial launch file. Now, I want to write a node that publishes to /joint_states and uses robot_state_publisher to update the robot. I'd like to display the robot in rviz, and also write a subscriber to /joint_states that moves the actual arm.

The problem I'm having is, when I write my own simple node to publish to /joint_states, rviz gives me errors for all of my joint transforms. (ie "no transform from [first_segment] to [base_link]" and "no transform from [second_segment] to [base_link]", also there's "Fixed Frame: No tf data. Actual error: Fixed Frame [base_link] does not exist"

I've looked at the documentation for robot_state_publisher, read the code for joint_state_publisher and tried manually sending tf's through my node.

I use this command to put in my urdf and launch the code:

roslaunch launch/display.launch model:=urdf/josh-arm.urdf


Here's my urdf, launch file, and python code (sorry I couldn't attach it.. don't have enough karma):

Thanks!

<launch>

<arg name="model" />
<arg name="gui" default="true" />
<arg name="rvizconfig" default="$(find urdf_tutorial)/rviz/urdf.rviz" /> <param name="robot_description" command="$(find xacro)/xacro.py $(arg model)" /> <param name="use_gui" value="$(arg gui)"/>

<node name="updateArm" pkg="me439arm" type="updateArm.py"/>
<node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
<node name="rviz" pkg="rviz" type="rviz" args="-d \$(arg rvizconfig)" required="true" />

</launch>


The urdf file:

<?xml version="1.0"?>
<robot name="visual">

<material name="blue">
<color rgba="0 0 0.8 1"/>
</material>
<material name="black">
<color rgba="0 0 0 1"/>
</material>
<material name="white">
<color rgba="1 1 1 1"/>
</material>

<visual>
<geometry>
</geometry>
</visual>

<visual>
<geometry>
</geometry>
<origin rpy="0 0 0" xyz="0 0 .1026"/>
<material name="white"/>
</visual>

<joint name="base_joint" type="revolute">
<axis xyz=" 0 0 1"/>
<origin rpy="0 0 0" xyz="0 0 0"/>
<limit effort="1000.0" lower="-3.14159" upper="3.14159" velocity=".5"/>
</joint>

<visual>
<geometry>
</geometry>
<origin rpy="0 0 0" xyz="-.0310 0 .059"/>
<material name="white"/>
</visual>

<joint name="first_segment_joint" type="revolute">
<axis rpy="0 1 0" xyz="0 1 0"/>
<origin rpy="0 0 0" xyz="0 0 .1"/>
<limit effort="1000.0" lower="-3.14159" upper="3.14159" velocity=".5"/>
</joint>

<visual>
<geometry>
</geometry>
<origin rpy="0 0 0" xyz="0 0 .01"/>
<material name="white"/>
</visual>

<joint name="second_segment_joint" type="revolute">
<axis rpy="0 1 0" xyz="0 1 0"/>
<origin rpy="0 0 0" xyz="-.0310 0 .1180"/>
<limit effort="1000.0" lower="-3.14159" upper="3 ...
edit retag close merge delete

1

Don't worry about not being able to your code as a file. It's actually better to include the code in the question as you have done here.

( 2017-11-08 23:54:04 -0500 )edit

Sort by » oldest newest most voted

A robot driver (but that is what we're talking about here) typically only needs to publish JointState messages, the rest will be taken care of by the robot_state_publisher (using forward kinematics).

An exception to this would be if you have 'strange' joint types which cannot be modelled properly in urdf or for which it doesn't make sense to go through JointState msgs first: then the driver would have to publish the corresponding TF frames itself (and the joints should not be part of the urdf in that case).

So having a robot_description parameter with a valid urdf, your driver + RSP should be enough to make RViz happy (and result in a working system, at least for displaying robot state).

and also write a subscriber to /joint_states that moves the actual arm.

I'm a little confused by this: /joint_states is for reporting state of your robot, not for controlling it.

Edit:

Okay, so i was using joint_state_publisher before to change the arms location on rviz, but that's only changing what's reported by the robot?

Well, that depends on what you consider "the robot": if you're just playing with your urdf, then you typically use the JSP to publish some fake JointState msgs where the values are taken from the sliders in the GUI.

With a real robot you would not use this, as your driver would be the entity publishing JointState msgs.

How can I control the joint angles? Is there a way to set joint angles and have RSP calculate the tf's for me? T

The RSP will always calculate TFs for you, provided that you got your urdf loaded and you have JointState msgs published by 'something' (ie: your driver). That is not influenced by whether or not you can control your robot.

Typical ROS robot drivers (for arms at least, but I'm guessing that is what you have) could implement a FollowJoinTrajectory action server. That would accept a JointTrajectory together with some constraints and would translate that into motions of the arm corresponding to what the trajectory prescribes (in space and time).

If you're writing a new driver you could perhaps take a look at ros_control. It's a framework that comes with a lot of infrastructure already so removes the need to develop things like that FollowJointTrajectory action server, controllers and state publishers. The 'only' thing you need to do is write a small hardware_interface class that allows ros_control to read out state and write new setpoints to your robot (and/or its controller).

ros_control is a bit of an advanced subject (and C++ only at the moment), so might be out of scope for now. I just wanted to mention it as it is a good example of an area where software re-use can really speed up your development.

more

Okay, so i was using joint_state_publisher before to change the arms location on rviz, but that's only changing what's reported by the robot? How can I control the joint angles? Is there a way to set joint angles and have RSP calculate the tf's for me? That's what I really want. Thanks!

( 2017-11-09 10:50:40 -0500 )edit

This is really awesome. I think my application is strange because we use servos for the arm, so there's no feedback (this is just for a class I teach). Writing a hardware interface shouldn't be a problem, and the JointTrajectories seem pretty straightforward. Thanks again!

( 2017-11-09 11:43:28 -0500 )edit
1

If you're going with ros_control, you might want to take a look at Dave Coleman's ros_control_boilerplate. It includes even more of the 'standard' stuff, so you have to do even less (fill in read() and write()).

( 2017-11-09 11:52:52 -0500 )edit
1

I think my application is strange because we use servos for the arm, so there's no feedback

doesn't matter. The principles remain the same.

ros_control includes a few forwarding command controllers, which don't do any closed loop control, just forward setpoints. Those would probably ..

( 2017-11-09 11:54:03 -0500 )edit
1

.. work nicely with your servos.

I'd also recommend trying to find some hardware_interface implementations for Dynamixels (and similar servos). There are a few and you could probably learn from those.

( 2017-11-09 11:54:38 -0500 )edit

Thanks! I'll check out the hardware_interfaces and the forward commanding controller. We've wrote the whole control code in python before, so I think using ros for some of it will be a huge upgrade. Especially since we can do a lot more in simulation, and we're teaching it to them anyway.

( 2017-11-09 12:49:52 -0500 )edit