Error: Joint is missing a parent and/or child -> No TF data
Hi all,
I'm trying to build a robotic arm, but I'm having troubles when I create the macro to simplify the code. I have the next error:
Failed to build tree: Joint [module_1_length_yaw_joint] is missing a parent and/or child link specification.
I have try to solve it modifying the code as many times I imagine it could works, but anyway it didn't work.
EDIT: This part is solve at this moment, but after this solution, there is no TF data received. Although the robot is correctly display in Gazebo the is only TF for the 2 firsts links.
-- LAUNCH FILE --
<?xml version="1.0"?>
<launch>
<!--arg name="robot_model" default="summit_xl_std.urdf.xacro"/-->
<arg name="robot_model" default="robot.xacro"/>
<arg name="x" default="2.0"/>
<arg name="y" default="0.0"/>
<arg name="z" default="0.0"/>
<!-- Load the URDF into ROS parameter server -->
<!--arg name="urdf_file" default="$(find xacro)/xacro '$(find summit_xl_description)/robots/$(arg robot_model)' inorder" /-->
<arg name="urdf_file" default="$(find xacro)/xacro '$(find arm_description)/urdf/$(arg robot_model)'" />
<param name="robot_description" command="$(arg urdf_file)" />
<!-- Gazebo -->
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(find arm_gazebo)/worlds/crasar_complete.world"/>
</include>
<!-- Spawn a robot into Gazebo -->
<node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model"
args="-param robot_description
-urdf
-x '$(arg x)'
-y '$(arg y)'
-z '$(arg z)'
-model fotokite"/>
<!-- send fake joint values -->
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher">
<!--param name="use_gui" value="FALSE"/-->
</node>
<!-- convert joint states to TF transforms for rviz, etc -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"
respawn="false" output="screen">
<remap from="/joint_states" to="/fotokite/joint_states" />
</node>
</launch>
-- /LAUNCH FILE
-- XACRO CALLER --
<?xml version="1.0"?>
<robot name="fotokite" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:include filename="$(find arm_description)/urdf/fotokite.urdf.xacro" />
<gazebo>
<plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
<robotNamespace>/fotokite</robotNamespace>
</plugin>
</gazebo>
<link name="world"/>
<!-- Fotokite -->
<fotokite_arm parent="world">
<origin xyz="0 0 0" rpy="0 0 0" />
</fotokite_arm>
</robot>
-- /XACRO CALLER --
Here is the code for the macro that is called to create the robotic arm:
-- CODE --
<?xml version="1.0"?>
<robot name="fotokite" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:macro name="fotokite_arm" params="parent *origin">
<xacro:property name="PI" value="3.14159265359"/>
<!-- Joints Control in Gazebo -->
<!--gazebo>
<plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so"/>
</gazebo-->
<!-- Geometrical properties -->
<xacro:property name="link_side" value="0.04"/>
<xacro:property name="joint_radius" value="0.018"/>
<xacro:property name="joint_length" value="0.025"/>
<xacro:property name="length" value="0.04"/>
<xacro:property name="mass" value="1.0"/>
<!-- Materials -->
<material name="orange">
<color rgba="1.00 0.67 0.02 1.00"/>
</material>
<material name="gray">
<color rgba="0.80 0.80 0.80 1.00"/>
</material>
<!-- Generates a box visual/collision/inertial -->
<xacro:macro name="prism_vci" params="side length mass:=1 *origin">
<xacro:macro name="prism_geometry">
<xacro:insert_block name="origin"/>
<geometry>
<box size="${side} ${side} ${length}"/>
</geometry>
</xacro:macro>
<visual>
<xacro:prism_geometry/>
<material name="orange"/>
</visual>
<collision>
<xacro:prism_geometry/>
</collision>
<inertial>
<xacro:insert_block name="origin"/>
<mass value="${mass}"/>
<inertia ixx="${(mass/12)*(side*side+length*length)}"
iyy="${(mass/12)*(side*side+length*length)}"
izz="${(mass/6)*(side*side)}"
ixy="0" ixz="0" iyz="0"/>
</inertial>
</xacro:macro>
<!-- Generates a cylinder visual/collision -->
<xacro:macro name="cylinder_vc" params="radius length *origin">
<xacro:macro name="cylinder_geometry">
<xacro:insert_block name="origin"/>
<geometry>
<cylinder length="${length}" radius="${radius}"/>
</geometry>
</xacro:macro>
<visual>
<xacro:cylinder_geometry/>
<material name="gray"/>
</visual>
<collision>
<xacro:cylinder_geometry/>
</collision>
</xacro:macro>
<!-- Generates child joint of parent -->
<xacro:macro name="arm_joint" params="prefix parent child axis dist:=0 joint_type lower upper index">
<!--xacro:unless value="${child == 'arm'}"-->
<joint name="${prefix}_${parent}_${child}_joint" type="${joint_type}">
<origin xyz="0 0 ${dist}" rpy="0 0 0"/>
<parent link="${prefix}_${parent}"/>
<xacro:if value="${index == 0}">
<child link="${prefix}_${child}"/>
</xacro:if>
<!--xacro:if value="${parent == 'length'}"-->
<xacro:if value="${index == 1}">
<child link="module_2_${child}"/>
</xacro:if>
<xacro:if value="${index == 2}">
<child link="module_3_${child}"/>
</xacro:if>
<xacro:if value="${index == 3}">
<child link="wrist_${child}"/>
</xacro:if>
<!--/xacro:if-->
<axis xyz="${axis}"/>
<limit effort="40.0"
velocity="1.0"
lower="${lower}"
upper="${upper}"/>
</joint>
<!-- Transmission -->
<!--transmission name="${parent}_${child}_transmission">
<type>transmission_interface/SimpleTransmission</type>
<joint name="${prefix}_${parent}_${child}_joint">
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
</joint>
<actuator name="${prefix}_${parent}_${child}_actuator">
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission-->
<!-- Links -->
<link name="${prefix}_${parent}">
<xacro:prism_vci length="${dist}" side="${link_side}">
<origin xyz="0 0 ${dist/2}" rpy="0 0 0"/>
</xacro:prism_vci>
<xacro:cylinder_vc radius="${joint_radius}" length="${joint_length}">
<xacro:if value="${axis=='0 0 1'}">
<origin xyz="0 0 ${dist}" rpy="0 0 0"/>
</xacro:if>
<xacro:if value="${axis=='1 0 0'}">
<origin xyz="0 0 ${dist}" rpy="0 ${PI/2} 0"/>
</xacro:if>
<xacro:if value="${axis=='0 1 0'}">
<origin xyz="0 0 ${dist}" rpy="${PI/2} 0 0"/>
</xacro:if>
</xacro:cylinder_vc>
</link>
<gazebo reference="${prefix}_${parent}">
<xacro:if value="${prefix == 'module_1'}">
<material>Gazebo/Orange</material>
</xacro:if>
<xacro:if value="${prefix == 'module_2'}">
<material>Gazebo/Blue</material>
</xacro:if>
<xacro:if value="${prefix == 'module_3'}">
<material>Gazebo/Yellow</material>
</xacro:if>
<xacro:if value="${prefix == 'wrist'}">
<material>Gazebo/Green</material>
</xacro:if>
</gazebo>
</xacro:macro>
<!-- Uncomment for RViz with fake joints -->
<!-- Uncomment for Gazebo -->
<!--link name="${parent}"/-->
<!-- Uncomment for RViz with fake joints -->
<!-- Uncomment for Gazebo -->
<!-- Arm fixed to world frame -->
<!-- Joints Chain -->
<xacro:arm_joint prefix="module_1" parent="yaw" child="pitch" axis="0 0 1" dist="${length}" joint_type="revolute" lower="${-PI}" upper="${PI}" index="0"/>
<xacro:arm_joint prefix="module_1" parent="pitch" child="roll" axis="0 1 0" dist="${length}" joint_type="revolute" lower="${-PI}" upper="${PI}" index="0"/>
<xacro:arm_joint prefix="module_1" parent="roll" child="length" axis="1 0 0" dist="${length}" joint_type="revolute" lower="${-PI}" upper="${PI}" index="0"/>
<xacro:arm_joint prefix="module_1" parent="length" child="yaw" axis="0 0 1" dist="${length}" joint_type="prismatic" lower="0" upper="2" index="1"/>
<xacro:arm_joint prefix="module_2" parent="yaw" child="pitch" axis="0 0 1" dist="${length}" joint_type="revolute" lower="${-PI}" upper="${PI}" index="0"/>
<xacro:arm_joint prefix="module_2" parent="pitch" child="roll" axis="0 1 0" dist="${length}" joint_type="revolute" lower="${-PI}" upper="${PI}" index="0"/>
<xacro:arm_joint prefix="module_2" parent="roll" child="length" axis="1 0 0" dist="${length}" joint_type="revolute" lower="${-PI}" upper="${PI}" index="0"/>
<xacro:arm_joint prefix="module_2" parent="length" child="yaw" axis="0 0 1" dist="${length}" joint_type="prismatic" lower="0" upper="2" index="2"/>
<xacro:arm_joint prefix="module_3" parent="yaw" child="pitch" axis="0 0 1" dist="${length}" joint_type="revolute" lower="${-PI}" upper="${PI}" index="0"/>
<xacro:arm_joint prefix="module_3" parent="pitch" child="roll" axis="0 1 0" dist="${length}" joint_type="revolute" lower="${-PI}" upper="${PI}" index="0"/>
<xacro:arm_joint prefix="module_3" parent="roll" child="length" axis="1 0 0" dist="${length}" joint_type="revolute" lower="${-PI}" upper="${PI}" index="0"/>
<xacro:arm_joint prefix="module_3" parent="length" child="pitch" axis="0 0 1" dist="${length}" joint_type="prismatic" lower="0" upper="2" index="3"/>
<xacro:arm_joint prefix="wrist" parent="pitch" child="yaw" axis="0 1 0" dist="${length}" joint_type="revolute" lower="${-PI}" upper="${PI}" index="0"/>
<xacro:arm_joint prefix="wrist" parent="yaw" child="roll" axis="0 0 1" dist="${length}" joint_type="revolute" lower="${-PI}" upper="${PI}" index="0"/>
<xacro:arm_joint prefix="wrist" parent="roll" child="finger" axis="1 0 0" dist="${length}" joint_type="revolute" lower="${-PI}" upper="${PI}" index="0"/>
<link name="wrist_finger">
<inertial>
<mass value="1.477" />
<origin xyz="0 0 0" />
<inertia ixx="0.01152" ixy="0.0" ixz="0.0" iyy="0.01152" iyz="0.0" izz="0.0218" />
</inertial>
<visual>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<mesh filename="package://arm_description/meshes/ardrone.dae"/>
</geometry>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<!--mesh filename="package://arm_description/urdf/ardrone.dae"/-->
<box size="0.001 0.001 0.001"/>
</geometry>
</collision>
</link>
<joint name="${parent}_module_1_joint" type="fixed">
<xacro:insert_block name="origin" />
<parent link="${parent}"/>
<child link="module_1_yaw"/>
</joint>
<!--gazebo reference="arm">
<material>Gazebo/Red</material>
</gazebo-->
</xacro:macro>
</robot>
-- /CODE --
Thank you for your help. Jorge
NOTE: I try to ask this question in Gazebo answers, but it says that is SPAM and doesn't publish the question
Asked by jdeleon on 2018-11-26 16:14:20 UTC
Answers
Your joint is missing a child. Every joint must have a child and a parent link.
http://wiki.ros.org/urdf/XML/joint
Try it with a useless link like
<link name="${child}_link" />
and insert in the joint
<child link = "${child}_link" />
Let me know if it works.
Edit: I see that you insert a child link in the joint, but you don't declare it anywhere.
Edit 2: I made it work here. The apostrophe indicate its a string type, if you're using a number, don't use it. Change the code
<xacro:if value="${parent == 'length'}">
<xacro:if value="${index == '1'}">
<child link="module_${index + 1}_${child}"/>
</xacro:if>
<xacro:if value="${index == '2'}">
<child link="module_${index + 1}_${child}"/>
</xacro:if>
<xacro:if value="${index == '3'}">
<child link="wrist_${child}"/>
</xacro:if>
</xacro:if>
to
<xacro:if value="${parent == 'length'}">
<xacro:if value="${index == 1}">
<child link="module_${index + 1}_${child}"/>
</xacro:if>
<xacro:if value="${index == 2}">
<child link="module_${index + 1}_${child}"/>
</xacro:if>
<xacro:if value="${index == 3}">
<child link="wrist_${child}"/>
</xacro:if>
</xacro:if>
Edit 3: Tf tree
Edit 4: You declared a macro named "fotokite_arm" but never instanced one. I added the following lines before </robot>
and it worked
<link name="world">
<origin xyz="0 0 0" rpy="0 0 0"/>
</link>
<xacro:fotokite_arm parent="world">
<origin xyz="0 0 0" rpy="0 0 0"/>
</xacro:fotokite_arm>
Edit 5: Here is the launcher I'm using. I'm calling the urdf "teste_2"
<?xml version="1.0"?>
<launch>
<param name="robot_description" command="$(find xacro)/xacro --inorder '$(find test_package)/urdf/teste_2.urdf.xacro'"/>
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
</launch>
Asked by FelipeNascimento on 2018-11-26 17:58:49 UTC
Comments
I have edit the question, the macro definition was not insert as code. Now you can see that I declare the child variable.
<xacro:macro name="arm_joint" params="prefix child parent dist:=0 axis joint_type lower upper index">
Asked by jdeleon on 2018-11-26 19:49:37 UTC
I solved it, I guess. The Index value is a number, so its not supposed to be inside ''. I'll edit the answer.
Asked by FelipeNascimento on 2018-11-27 14:32:13 UTC
Hi @FelipeNascimiento, finally your solution is right!!
But the problem is that now I can't get the TFs of the robot, I only get the world->module_1_yaw, but not the rest...
Do you know if there is any problem for calling the macro from another .xacro?
Thank you
Asked by jdeleon on 2018-11-28 11:35:19 UTC
Hey there, I'm getting the tfs right here. Of course I don't have the prism_vci and cylinder_vci macros you made, so I used a default origin for the link only for test. I'm updating the answer with a image of the tf tree.
Asked by FelipeNascimento on 2018-11-28 17:51:42 UTC
There is no problem in calling a macro in another macro, so it should be ok. Maybe double check your macros and make sure you're assigning an origin to the links
Asked by FelipeNascimento on 2018-11-28 17:57:21 UTC
If try changing the links (visual and collision) to the standard xacro form, and neither I can't get the TFs.
I update the original post with the prism_vci and cylinder_vci, to see if you can detect where is the error.
Thank you
Asked by jdeleon on 2018-11-28 23:23:28 UTC
You never instanced a 'fotokite_arm' macro, only declared one. I instanced one after the macro declaration and it worked here. I edited the answer.
Asked by FelipeNascimento on 2018-11-29 00:07:20 UTC
I have in another xacro what you say:
<!--Import Fotokite arm -->
<xacro:include filename="$(find arm_description)/urdf/fotokite.urdf.xacro" />
<link name="world"/>
<xacro:fotokite_arm parent="world">
<origin xyz="0 0 0" rpy="0 0 0" />
</xacro:fotokite_arm>
Asked by jdeleon on 2018-11-29 11:47:20 UTC
If I modify the code with your EDIT4 and launching only this xacro, I still can't get more TFs than the world and the module_1_yaw.
Here you can see the TFs https://ibb.co/TLQVmH1
Is like it didn't get the joints from the macro.
Asked by jdeleon on 2018-11-29 11:56:29 UTC
It works here. Are you launching joint_state_publisher and robot_state_publisher?
Asked by FelipeNascimento on 2018-11-29 15:20:18 UTC
I have add to the question my launch file and the macro file that calls the one with the macro.
I have also try to call the macro with two different forms:
<fotokite_arm parent="world">
<origin xyz="0 0 0" rpy="0 0 0" />
</fotokite_arm>
Asked by jdeleon on 2018-11-29 21:18:18 UTC
And with this form:
<xacro:fotokite_arm parent="world">
<origin xyz="0 0 0" rpy="0 0 0" />
</xacro:fotokite_arm>
But doesn't work with any
Asked by jdeleon on 2018-11-29 21:19:23 UTC
Comments
If I comment the first if for the child
The error is different:
Asked by jdeleon on 2018-11-26 19:56:16 UTC
Have you tried converting your xacro file into urdf to directly see the values of the variables ? You would directly see all the children and parents like that (see #q10401).
Asked by Delb on 2018-11-27 02:37:34 UTC
Hi @Delb, I had the same error if I try to convert to URDF.
Asked by jdeleon on 2018-11-28 22:31:47 UTC