ADVRHumanoids/xbot2_examples

Pid gains are always necessary for each joint

Closed this issue · 4 comments

Hi, I found out that in the urdf you have to set the pid for each non-fixed joint, otherwise they are probably set to strange value, causing the model to explode.
I say this because when the pid for each joints, the model does not explode anymore:

<pid>
            <gain name="small_mot"  p="0.1"  d="0.05"/>
            <gain name="medium_mot" p="1000" d="10"/>
            <gain name="big_mot"    p="3000" d="10"/>
            <gain name="wheel_mot"  p="0" d="30"/>
            <gain name="null"  p="0" d="0" i="0"/>

            <gain name="finger_joint" profile="null"/>
           <gain name="left_outer_finger_joint" profile="null"/>
            <gain name="left_inner_finger_joint" profile="null"/>
            <gain name="left_inner_finger_pad_joint" profile="null"/>
            
            <gain name="right_outer_finger_joint" profile="null"/>
            <gain name="right_inner_finger_joint" profile="null"/>
            <gain name="right_inner_finger_pad_joint" profile="null"/>
            
            <gain name="left_inner_knuckle_joint" profile="null"/>
            <gain name="right_inner_knuckle_joint" profile="null"/>
            <gain name="right_outer_knuckle_joint" profile="null"/>
</pid>

This is not what I expect: for mimic joints, I do not want to set a pid (yes, I can set it to zero anyway).

Maybe it can be solved by initializing the pid to zero in src/gazebo/src/joint/xbot2_gz_joint_server.cpp ? Like:

 for(auto& gz_j : model->GetJoints())
    {

        if(gz_j->HasType(gz::physics::Joint::FIXED_JOINT))
        {
            continue;
        }

        gzlog << fmt::format("found joint '{}' \n", gz_j->GetName());

        Hal::DeviceInfo devinfo{gz_j->GetName(),
                                "joint_gz",
                                id++};

        auto hal_joint = std::make_shared<JointInstanceGz>(devinfo,
                                                           gz_j);

        _jptr_vec.push_back(hal_joint);

       	// initialize pid gains so model does not explode if for some joint the pid is not written in urdf 
        // (as normal for mimic)
	hal_joint->tx().gain_kp = 0;
        hal_joint->tx().gain_kd = 0;

        // this map is used later on to set the gains
        jptr_map[devinfo.name] = hal_joint;
    }

There is not a way to detect mimic joint in gazebo, the mimic tag is not supported (and they are considered as all the other active "revolute" /"prismatic")

The default gain value is given by the following code:

JointInstanceGz::JointInstanceGz(DeviceInfo devinfo,
                                 gz::physics::JointPtr gz_joint):
    BaseType(devinfo),
    _gz_joint(gz_joint)
{
    _tx.gain_kp = 100;
    _tx.gain_kd = 5;
}

Probably it was too high for your use case scenario (involving probably very low inertias)

Yes, as you see I need like 0.1 for hands :D

Is there a reason to init it at 100 and 5 instead 0 and 0? I would expect a 0 gain if I do not set anything it in the <pid> tag

We need a default (>0) gain setting otherwise the robot will not be able to win the gravity at the start of the simulation.
Moreover this replicates the current hardware setup of the motors in our robots that start with a certain gains value.

Ok, understood. We can probably close this, then