0

Rosanswers logo

Hello, guys

I'd like to know how do I create a 3D ball joint using URDF.

I've tried some approaches like trying to create a dummy link, but I had no success.

In my project I have a quadrotor and a ball, I'd like to fix them, so the quad could roll, pitch and yaw on a fixed spot.

Any thoughts about that?

EDIT

I'll give more explanation about my problem.

In my project I want to develop a system for drones to share payload, and I want to avoid the problem of collision keeping them fixed in distance. To achieve that, I had the idea of using a bar, where they would be able to move freely. The image above ilustrates the ideia with one quad.

https://ibb.co/efGc3v

The problem that I'm facing right now is with the spherical joint between the quad and the ball. I managed to achieve 1 DoF at the moment. I'll copy here the 3 files that I'm using to make it work.

The bar model:

<?xml version="1.0"?>

<robot xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:property name="M_PI" value="3.1415926535897931"/>

&lt;xacro:macro name=&quot;barra_model&quot; params=&quot;name parent *origin&quot;&gt;
  &lt;joint name=&quot;<span class="math-container">${name}_joint" type="fixed"&gt;
    &lt;xacro:insert_block name="origin" /&gt;
    &lt;parent link="$</span>{parent}&quot;/&gt;
    &lt;child link=&quot;barra_baselink&quot;/&gt;
  &lt;/joint&gt;

  &lt;link name=&quot;barra_baselink&quot;&gt;
    &lt;visual&gt;
      &lt;geometry&gt;
        &lt;sphere radius=&quot;0.025&quot;/&gt;
      &lt;/geometry&gt;
  &lt;origin rpy=&quot;0 0 0&quot; xyz=&quot;0.9875 0 0.1125&quot;/&gt;
      &lt;material name=&quot;white&quot;&gt;
        &lt;color rgba=&quot;1 1 1 1&quot;/&gt;
      &lt;/material&gt;
    &lt;/visual&gt;
    &lt;inertial&gt;
      &lt;mass value=&quot;0.025&quot; /&gt;
      &lt;origin xyz=&quot;0.9875 0 0.1125&quot; rpy=&quot;0 0 0&quot; /&gt;
      &lt;inertia ixx=&quot;5.8083e-4&quot; ixy=&quot;0&quot; ixz=&quot;0&quot; iyy=&quot;3.0833e-5&quot; iyz=&quot;0&quot; izz=&quot;5.9083e-4&quot; /&gt;
    &lt;/inertial&gt;
&lt;collision&gt;
      &lt;geometry&gt;
        &lt;sphere radius=&quot;0.025&quot;/&gt;
      &lt;/geometry&gt;
  &lt;origin rpy=&quot;0 0 0&quot; xyz=&quot;0.9875 0 0.1125&quot;/&gt;
    &lt;/collision&gt;
  &lt;/link&gt;   

  &lt;joint name=&quot;<span class="math-container">${name}_b2ebase_link" type="fixed"&gt;
  &lt;parent link="barra_baselink"/&gt;
      &lt;child link="$</span>{name}_b2&quot;/&gt;
  &lt;/joint&gt;

&lt;link name=&quot;${name}_b2&quot;&gt;
    &lt;visual&gt;
      &lt;geometry&gt;
        &lt;box size=&quot;0.025 0.025 0.10&quot;/&gt;
      &lt;/geometry&gt;
  &lt;origin rpy=&quot;0 0 0&quot; xyz=&quot;0.9875 0 0.075&quot;/&gt;
    &lt;/visual&gt;
    &lt;inertial&gt;
      &lt;mass value=&quot;0.050&quot; /&gt;
      &lt;origin xyz=&quot;0.9875 0 0.075&quot; rpy=&quot;0 0 0&quot; /&gt;
      &lt;inertia ixx=&quot;5.8083e-4&quot; ixy=&quot;0&quot; ixz=&quot;0&quot; iyy=&quot;3.0833e-5&quot; iyz=&quot;0&quot; izz=&quot;5.9083e-4&quot; /&gt;
    &lt;/inertial&gt;
&lt;collision&gt;
      &lt;geometry&gt;
        &lt;box size=&quot;0.05 0.05 0.20&quot;/&gt;
      &lt;/geometry&gt;
  &lt;origin rpy=&quot;0 0 0&quot; xyz=&quot;0.9875 0 0.075&quot;/&gt;
    &lt;/collision&gt;
  &lt;/link&gt;

  &lt;joint name=&quot;<span class="math-container">${name}_b1eb2" type="fixed"&gt;
  &lt;parent link="$</span>{name}_b2&quot;/&gt;
      &lt;child link=&quot;${name}_bhor&quot;/&gt;
  &lt;/joint&gt;

  &lt;link name=&quot;${name}_bhor&quot;&gt;
    &lt;visual&gt;
      &lt;geometry&gt;
        &lt;box size=&quot;2.0 0.025 0.025&quot;/&gt;
      &lt;/geometry&gt;
  &lt;origin rpy=&quot;0 0 0&quot; xyz=&quot;0 0 0.0125&quot;/&gt;
    &lt;/visual&gt;
    &lt;inertial&gt;
      &lt;mass value=&quot;0.253&quot; /&gt;
      &lt;origin xyz=&quot;0 0 0&quot; rpy=&quot;0 0 0.0125&quot; /&gt;
      &lt;inertia ixx=&quot;5.8083e-4&quot; ixy=&quot;0&quot; ixz=&quot;0&quot; iyy=&quot;3.0833e-5&quot; iyz=&quot;0&quot; izz=&quot;5.9083e-4&quot; /&gt;
    &lt;/inertial&gt;
&lt;collision&gt;
      &lt;geometry&gt;
        &lt;box size=&quot;2.0 0.025 0.025&quot;/&gt;
      &lt;/geometry&gt;
  &lt;origin rpy=&quot;0 0 0&quot; xyz=&quot;0 0 0.0125&quot;/&gt;
    &lt;/collision&gt;
  &lt;/link&gt;

  &lt;joint name=&quot;<span class="math-container">${name}_b1eb3" type="fixed"&gt;
  &lt;parent link="$</span>{name}_bhor&quot;/&gt;
      &lt;child link=&quot;${name}_b3&quot;/&gt;
  &lt;/joint&gt;

  &lt;link name=&quot;${name}_b3&quot;&gt;
    &lt;visual&gt;
      &lt;geometry&gt;
        &lt;box size=&quot;0.025 0.025 0.10&quot;/&gt;
      &lt;/geometry&gt;
  &lt;origin rpy=&quot;0 0 0&quot; xyz=&quot;-0.9875 0 0.075&quot;/&gt;
    &lt;/visual&gt;
    &lt;inertial&gt;
      &lt;mass value=&quot;0.050&quot; /&gt;
      &lt;origin xyz=&quot;-0.9875 0 0.075&quot; rpy=&quot;0 0 0&quot; /&gt;
      &lt;inertia ixx=&quot;5.8083e-4&quot; ixy=&quot;0&quot; ixz=&quot;0&quot; iyy=&quot;3.0833e-5&quot; iyz=&quot;0&quot; izz=&quot;5.9083e-4&quot; /&gt;
    &lt;/inertial&gt;
&lt;collision&gt;
      &lt;geometry&gt;
        &lt;box size=&quot;0.025 0.025 0.20&quot;/&gt;
      &lt;/geometry&gt;
  &lt;origin rpy=&quot;0 0 0&quot; xyz=&quot;-0.9875 0 0.075&quot;/&gt;
    &lt;/collision&gt;
  &lt;/link&gt;

  &lt;joint name=&quot;<span class="math-container">${name}_b3ebase_link2" type="fixed"&gt;
  &lt;parent link="$</span>{name}_b3&quot;/&gt;
      &lt;child link=&quot;${name}_link2&quot;/&gt;
  &lt;/joint&gt;  

  &lt;link name=&quot;${name}_link2&quot;&gt;
    &lt;visual&gt;
      &lt;geometry&gt;
        &lt;sphere radius=&quot;0.025&quot;/&gt;
      &lt;/geometry&gt;
  &lt;origin rpy=&quot;0 0 0&quot; xyz=&quot;-0.9875 0 0.1125&quot;/&gt;
      &lt;material name=&quot;white&quot;/&gt;
    &lt;/visual&gt;
    &lt;inertial&gt;
      &lt;mass value=&quot;0.050&quot; /&gt;
      &lt;origin xyz=&quot;-0.9875 0 0.1125&quot; rpy=&quot;0 0 0&quot; /&gt;
      &lt;inertia ixx=&quot;5.8083e-4&quot; ixy=&quot;0&quot; ixz=&quot;0&quot; iyy=&quot;3.0833e-5&quot; iyz=&quot;0&quot; izz=&quot;5.9083e-4&quot; /&gt;
    &lt;/inertial&gt;
&lt;collision&gt;
      &lt;geometry&gt;
        &lt;sphere radius=&quot;0.025&quot;/&gt;
      &lt;/geometry&gt;
  &lt;origin rpy=&quot;0 0 0&quot; xyz=&quot;-0.9875 0 0.1125&quot;/&gt;
    &lt;/collision&gt;
  &lt;/link&gt;   

&lt;/xacro:macro&gt;

&lt;xacro:macro name=&quot;barra_&quot; params=&quot;name parent *origin&quot;&gt;
  &lt;xacro:barra_model name=&quot;<span class="math-container">${name}" parent="$</span>{parent}&quot;&gt;
    &lt;xacro:insert_block name=&quot;origin&quot; /&gt;
  &lt;/xacro:barra_model&gt;


&lt;/xacro:macro&gt;
&lt;/robot&gt;

The link to make the joint:

<?xml version="1.0"?>

<robot xmlns:xacro="http://www.ros.org/wiki/xacro">

&lt;xacro:macro name=&quot;junta_model&quot; params=&quot;name parent child *origin&quot;&gt;
  &lt;joint name=&quot;{name}_joint&quot; type=&quot;continuous&quot;&gt;
    &lt;parent link=&quot;${parent}&quot;/&gt;
    &lt;child link=&quot;junta1&quot;/&gt;
&lt;axis xyz=&quot;0 1 0&quot; /&gt;
  &lt;/joint&gt;

  &lt;link name=&quot;junta1&quot; /&gt;

  &lt;joint name=&quot;<span class="math-container">${name}_jointfixed" type="fixed"&gt;
&lt;xacro:insert_block name="origin" /&gt;    
    &lt;parent link="junta1"/&gt;
    &lt;child link="$</span>{child}&quot;/&gt;
  &lt;/joint&gt;

&lt;/xacro:macro&gt;

</robot>

The urdf with quad + link + bar:

<?xml version="1.0"?>

<robot name="quadrotor" xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:property name="M_PI" value="3.1415926535897931"/>

&lt;xacro:include filename=&quot;$(find hector_quadrotor_description)/urdf/quadrotor_base.urdf.xacro&quot; /&gt;
&lt;xacro:quadrotor_base_macro /&gt;

&lt;xacro:include filename=&quot;$(find hector_sensors_description)/urdf/juntayaw.urdf.xacro&quot; /&gt;
&lt;xacro:junta_model name=&quot;juntayaw&quot; parent=&quot;base_link&quot; child=&quot;barra_baselink&quot;&gt;
  &lt;origin xyz=&quot;0.485 0 -0.07&quot; rpy=&quot;0 0 0&quot;/&gt;
&lt;/xacro:junta_model&gt;

&lt;xacro:include filename=&quot;$(find hector_sensors_description)/urdf/barra.urdf.xacro&quot; /&gt;
&lt;xacro:barra_model name=&quot;barra&quot; parent=&quot;junta1&quot;&gt;
  &lt;origin xyz=&quot;0 0 0&quot; rpy=&quot;0 0 0&quot;/&gt;
&lt;/xacro:barra_model&gt;


</robot>

The result with Pitch angle: https://ibb.co/b1XTAa

When I try to add a second DoF, my bar disappears:

<?xml version="1.0"?>

<robot xmlns:xacro="http://www.ros.org/wiki/xacro">

&lt;xacro:macro name=&quot;junta_model&quot; params=&quot;name parent child *origin&quot;&gt;
  &lt;joint name=&quot;{name}_joint&quot; type=&quot;continuous&quot;&gt;
    &lt;parent link=&quot;${parent}&quot;/&gt;
    &lt;child link=&quot;junta1&quot;/&gt;
&lt;axis xyz=&quot;0 1 0&quot; /&gt;
  &lt;/joint&gt;

  &lt;link name=&quot;junta1&quot; /&gt;

  &lt;joint name=&quot;{name}_joint2&quot; type=&quot;continuous&quot;&gt;
    &lt;parent link=&quot;junta1&quot;/&gt;
    &lt;child link=&quot;junta2&quot;/&gt;
&lt;axis xyz=&quot;0 0 1&quot; /&gt;
  &lt;/joint&gt;

  &lt;link name=&quot;junta2&quot; /&gt;

  &lt;joint name=&quot;<span class="math-container">${name}_jointfixed" type="fixed"&gt;
&lt;xacro:insert_block name="origin" /&gt;    
    &lt;parent link="junta2"/&gt;
    &lt;child link="$</span>{child}&quot;/&gt;
  &lt;/joint&gt;

&lt;/xacro:macro&gt;

</robot>

https://ibb.co/cs1AOv

Another approach that I tried was to change the relation between Quad and Bar, to make the Quad as child and the Bar as parent, but then, my controller stops working and I can't fly the Quad anymore.

Please, if you need more information to understand the problem, just ask then I will try to make it more clear.

Thanks in advance

Pedro


Originally posted by PedroHRPBS on ROS Answers with karma: 13 on 2017-04-01

Post score: 0

2 Answers2

0

Rosanswers logo

I think by "ball joint", you are talking about a single joint with 3 mutually-orthogonal rotational degrees-of-freedom -- often called a spherical joint. If this is indeed the case, in your URDF, you would need to build this joint by composing three separate joints and corresponding links of either the continuous or revolute type. Here's a small snippet copied from here as an example:

<!-- left shoulder -->
<joint name="LShoulder" type="fixed" >
    <origin xyz="0.15 0  0.043529411764705886" />
    <parent link="torso" />
    <child link="left_shoulder" />
</joint>
<link name="left_shoulder" />
<joint name="LShoulderPsi" type="continuous" >
    <parent link="left_shoulder" />
    <child link="left_shoulder_psi_link" />
    <axis xyz="0 0 1" />
    <dynamics damping="0.005" />
</joint>
<link name="left_shoulder_psi_link" />
<joint name="LShoulderTheta" type="continuous" >
    <parent link="left_shoulder_psi_link"/>
    <child link="left_shoulder_theta_link"/>
    <axis xyz="0 1 0" />
    <dynamics damping="0.005" />
</joint>
<link name="left_shoulder_theta_link" />
<joint name="LShoulderPhi" type="continuous" >
    <parent link="left_shoulder_theta_link"/>
    <child link="left_humerus"/>
    <axis xyz="1 0 0" />
    <dynamics damping="0.005" />
</joint>

In the above example, the spherical joint is described using ZYX relative-axis Euler angles.


Originally posted by jarvisschultz with karma: 9031 on 2017-04-02

This answer was NOT ACCEPTED on the original site

Post score: 1


Original comments

Comment by PedroHRPBS on 2017-04-02:
That's exactly what I meant. But it didn't work. I have a quadrotor (link1) and a bar with a ball in one end which I want to fix in the quad base with the spherical joint. If I try to create a continuous joint between them (quad as parent and bar as child) the quad rotates relative to the center of

Comment by PedroHRPBS on 2017-04-02:
Center of the bar. If I switch roles (bar as parent and quad as child) my controller which I use to fly the quad will stop working. When I create a third link between them, I can make 1 DoF work. But for some reason, when I try to implement your suggestion, when I add the second DoF

Comment by PedroHRPBS on 2017-04-02:
Second DoF my bar disappears when I spawn the model in Gazebo. I've tried many combinations, creating more links between them, editing the bar model, but everytime I add a second DoF the bar doesn't show up in Gazebo. I can't find a way out to solve this problem.

Comment by PedroHRPBS on 2017-04-02:
I thought about migrating to SDF but then I don't know how to make the plugins work nor how to spawn the model through ROS so I can control it with my xbox controller.

Comment by jarvisschultz on 2017-04-02:
The Gazebo/SDF stuff is far afield from your original question. If you have questions on these topics, I'd suggest opening new questions. It's difficult to understand what doesn't work and what you are trying to do. Perhaps you could edit your original question to provide more info, or ask new Q.

Comment by PedroHRPBS on 2017-04-04:
Hello, Jarvis, I just did what you said me to do. Thank you very much!

jarvisschultz
  • 3,760
  • 1
  • 12
  • 3
0

Rosanswers logo

The problem occurs because of two reasons:

  • Gazebo "merges" child links to their parent when they are connected via a fixed joint, creating only one link with the name of the parent link;
  • Gazebo ignores links without inertial properties

In the first case you have one link that has no inertia: "junta1". However, Gazebo merges all the links that are created by the "barra_model" macro into the "junta1" link, because they are all connected through fixed joints. Then "junta1" "gains" inertia, since the inertia objects of its child links now belong to it. Then it is not ignored.

In the second case, you have two links without inertia, "junta1" and "junta2". They are connected through a continuous joint, so Gazebo will not merge them. This lets "junta1" without inertia, and it gets ignored. Since there is no "junta1", all its children (i.e the whole bar) are not created. That's why the bar disappears.

The solution is to give a simple inertial block to the links, with a small mass. In the code below, I copied the same inertial properties from the spheres in the bar, and added the third link to create the ball joint.

<?xml version="1.0"?>

<robot xmlns:xacro="http://www.ros.org/wiki/xacro">

<xacro:macro name="junta_model" params="name parent child *origin">

<joint name="${name}_joint" type="continuous"> <parent link="base_link"/> <child link="junta1"/> <axis xyz="0 1 0" /> </joint>

<link name="junta1"> <inertial> <mass value="0.025" /> <inertia ixx="5.8083e-4" ixy="0" ixz="0" iyy="3.0833e-5" iyz="0" izz="5.9083e-4" /> </inertial> </link>

<joint name="${name}_joint2" type="continuous"> <parent link="junta1"/> <child link="junta2"/> <axis xyz="0 0 1" /> </joint>

<link name="junta2"> <inertial> <mass value="0.025" /> <inertia ixx="5.8083e-4" ixy="0" ixz="0" iyy="3.0833e-5" iyz="0" izz="5.9083e-4" /> </inertial>
</link>

<joint name="${name}_joint3" type="continuous"> <parent link="junta1"/> <child link="junta3"/> <axis xyz="1 0 0" /> </joint>

<link name="junta3"> <inertial> <mass value="0.025" /> <inertia ixx="5.8083e-4" ixy="0" ixz="0" iyy="3.0833e-5" iyz="0" izz="5.9083e-4" /> </inertial>
</link>

<joint name="${name}_jointfixed" type="fixed"> <xacro:insert_block name="origin" />
<parent link="junta3"/> <child link="$
{child}"/> </joint> </xacro:macro>

</robot>

I hope it helps.


Originally posted by RafaelGB with karma: 106 on 2017-04-11

This answer was ACCEPTED on the original site

Post score: 8


Original comments

Comment by PedroHRPBS on 2017-04-11:
it worked! thank you very much for the explanation!