# xacro: parametrable constants?

Hi.

I'm working on a robotic arm and I have this code block 5 times in my urdf file:

  <!-- arm_1 link -->
<inertial>
<mass value="${arm_1_link_mass}" /> <inertia ixx="0.010" ixy="0.000" ixz="0.000" iyy="0.010" iyz="0.000" izz="0.010" /> </inertial> <visual> <geometry> <mesh filename="package://youbot_description/meshes/arm_joint_1.dae"/> </geometry> </visual> </link> <!-- arm_1 joint --> <joint name="arm_1_joint" type="revolute"> <origin xyz="${arm_1_link_pose_x} ${arm_1_link_pose_y}${arm_1_link_pose_z}"
rpy="${arm_1_link_orient_r}${arm_1_link_orient_p} ${arm_1_link_orient_y}" /> <parent link="arm_base_link"/> <child link="arm_1_link" /> <axis xyz="${arm_1_axis}" />
<limit lower="${arm_1_limit_min}" upper="${arm_1_limit_max}"
effort="${arm_joint_effort}" velocity="${arm_joint_velocity}" />
</joint>


I would like to use a smart macro to only have one block called 5 times. I would ideally only use the joint number as a parameter. The values are stored on another file in xacro:property.

The issue: how to transform this ${arm_1_limit_min} with a parameter?${arm_${param_name}_limit_min} does not work. Thanks for your answers! edit retag close merge delete ## 2 Answers Sort by » oldest newest most voted I guess I was tired when I raise this question. The solution is to create one macro for the inertia and mass and another one for the origin, parent, origin and axis of the joint. The macros can be called dynamically with a single parameter. The specific arm part values have to be stored in the macros directly. That gives a very readable code, with 5 calls to a macro, calling sub-macros. And a set of five macros very close to the spec sheet of the arm parts. more ## Comments Hi, could you provide some example of your solution? I've tried using a macro that receives property id, and builds up property name while passing it as parameter to another macro. Unfortunately, it seems that the nested macro treats that param as a string and does not resolve it to a property. ( 2015-12-30 04:45:59 -0600 )edit Well, this question is a bit old, but you can look at this repo: https://github.com/Arn-O/youbot_ros_t... ( 2015-12-30 16:36:39 -0600 )edit Thanks for help. I see that u extracted inertias and joints to macros in separate file. This makes the code more readable, but it still requires copy-pasting of all the arm_id stuff and modifying the ids everywhere manually. Not exactly what I was looking for, but it seems that theres no better way. ( 2016-01-04 12:30:46 -0600 )edit One more question, do you recall what you meant by "The macros can be called dynamically with a single parameter." ? I don't see it in your repo, but calling a macro by dynamic names would be a solution. I see it in jade possible by xacro:call, unfortunatelly Im bound to previous releases ( 2016-01-04 13:00:34 -0600 )edit Correct, it is not that "dynamic". My assumption is that you cannot make it dynamic, since it is designed for robot description, and robot description are supposed to be "static". Not nice for coders, but XML is not really a programming language, just a markup language. ( 2016-01-05 09:36:31 -0600 )edit I think this should be able to do what you want. Xacro offers parameterized macros (specifically the "params" attribute in the macro definition): <xacro:macro name="blue_shape" params="name"> <link name="${name}">
....


I think the parameter functionality with simple concatenation (in the constants section http://wiki.ros.org/urdf/Tutorials/Using%20Xacro%20to%20Clean%20Up%20a%20URDF%20File#Constants):

<link name=”${robotname}s_leg” />  more ## Comments Thx for your answer. I know how to define a parameter ... the issue is that I need to define a property that should be based on the parameter. Let's say that you have a param "name", I need to use the name in a property. So it should be something like {$property_\${name}} but that does not work.

( 2013-09-30 09:14:42 -0600 )edit

Oh. I'm sorry, I didn't fully understand what you were asking until just now. I don't know how to do something like that. I would suggest passing in all the parameters to the macro instead of trying to construct them internally. Probably not the answer you wanted though.

( 2013-09-30 09:22:12 -0600 )edit

Thanks anyway for the time spent on it. I don't think we can do it easily. Passing all the parameters gives a pretty ugly code. An option would be to define block macro for the origin, limits, etc. and using the param to dynamically call those macros. Still have to code 5 times the blocks.

( 2013-09-30 09:28:33 -0600 )edit