美文网首页ROS · 机器人笔记
从零开始的ROS机械臂,边做边学02-URDF篇

从零开始的ROS机械臂,边做边学02-URDF篇

作者: DIO哒 | 来源:发表于2018-10-20 15:56 被阅读678次

    这一篇内容的成果大概长这样,因为比较简单,手写比较方便。

    显然,这是一个便宜的sg90舵机
    视频地址: https://www.bilibili.com/video/av34229434/

    关于urdf的介绍目前看到的最好的一篇介绍应该是ROSCon的这篇
    https://youtu.be/g9WHxOpAUns
    ROSWIKI上有完整的urdf教程,你可以根据教程自己写一些简单的机器人,实际上相当的麻烦而且容易出错,我以前从未想过用这种方法写一个机器人的模型出来,还以为和做游戏一样在Blender或者3dsmax这样的建模软件里搞定一切然后直接导出到rviz里就能摆弄了。实际上urdf也是可以的,但目前好像只有solidworks和matlab有这种插件,其中solidworks的插件叫做sw2urdf,我使用了之后发现还是相当方便的,至少比手写方便。

    catkin_create_pkg <你要创建的package的名字> roscpp tf  geometry_msgs urdf rviz xacro 
    

    创建好包之后我们来写urdf,目前好像没找到带urdf代码提示插件的文本编辑器,如果你使用带ros_qct_plugin的qtcreator的话里面可以新建urdf文件,但并没有提示功能。
    下面具体来写这个简单的sg90舵机的urdf文件的过程
    首先打开http://wiki.ros.org/urdf/XML
    urdf是一种XML格式的文件,参考上面的链接找到你需要的东西,主要是各种link和joint。
    上面这个舵机的模型由两个link和一个joint组成,下面蓝色的是舵机本体,上面红色的是买舵机的时候送的配件,非常便宜,随处可见。
    不能在urdf里直接写出它们模型,而是选择mesh型的link,从别的地方引用一个stl格式的模型。这里是用Blender简单的做了一个sg90的外形。
    做的时候看了一下比例,Blender里默认的box大小是2m2m2m,在urdf里直接写一个box型的link,size设置成“2 2 2”,两者的大小是一样的。如果懒得做模型的话直接搞两个box替代就好了。

    <?xml version="1.0"?>
    <robot name="my_01">
        <link name="base_link">
            <visual>
                <geometry>
                    <mesh filename="package://my_robot/meshes/servo_9g.stl" size="1 1 1" />
                </geometry>
                <material name="blue">
                    <color rgba="0 31 255 1"/>
                </material>
                <origin rpy="0 0 0" xyz="0 0 0" />
            </visual>
            <collision>
                <origin rpy="0 0 0" xyz="0 0 0" />
                <geometry>
                    <mesh filename="package://my_robot/meshes/servo_9g.stl" size="1 1 1" />
                </geometry>
            </collision>
        </link>
    
        <joint name="base_link_to_link_01" type="revolute">
            <parent link="base_link"/>
            <child link="link_01" />
            <origin xyz="0.5 0 1.4" />
            <axis xyz="0 0 -1" />
            <limit effort="2.5" velocity="0.1" lower="-1.57" upper="1.57" />
            <!-- <dynamics damping="0" friction="0" /> -->
        </joint>
    
        <link name="link_01">
            <visual>
                <geometry>
                    <mesh filename="package://my_robot/meshes/servo_9g_bar.stl" size="1 1 1" />
                </geometry>
                <origin rpy="0 0 0" xyz="0 0 0" />
            </visual>
            <collision>
                <geometry>
                    <mesh filename="package://my_robot/meshes/servo_9g_bar.stl" size="1 1 1" />
                </geometry>
                <origin rpy="0 0 0" xyz="0 0 0" />
            </collision>
        </link>
    </robot>
    
    

    其中joint是比较关键的部分,joint有很多种,比较常见的有

    • continuous 可以一直转下去
    • revolute 舵机一般用这种,可以从一个角度转到另一个角度,limit里设置一下就好了
    • prismatic 沿着一个导轨平移的东西就用它
    • fixed 什么也不干,只是把两个link就这么接在一起

    这里值得注意的是joint的

      <limit effort="2.5" velocity="0.1" lower="-1.57" upper="1.57" />
    

    我一度认为effort和velocity就是下图的torque和speed


    sg90_datasheet.pdf

    然而好像并不是,effort是百分数,velocity是每秒转动的弧度。
    所以目前填什么其实都无所谓,现阶段arduino只接收position就行了。

    这两个link实际上是从外部导入的stl格式的3d模型,但很多3d模型很复杂,所以有英伟达显卡的话最好能安装一下驱动程序,另外要准备一份低模,也就是面数比较低的模型,俗称low-poly,作为机器人的碰撞体collision,外形和尺寸要和你的用于显示的高模差不多,origin当然也要设置成一样的。

    另外需要注意的是joint的位置和旋转的轴,这点在上面那个ROSCon的视频里有比较直观的讲解。写的时候脑子未必能转的过来,需要时不时打开rviz查看模型是否正确,所以这个时候就需要写一个launch文件来启动rviz。这里顺便一说atom有一个ros代码提示的package,可以用来写launch文件,大概长这样:


    atom-ros
    <launch>
        <arg name="model" />
        <param name="robot_description" textfile="$(find my_robot)/urdf/my01.urdf" />
        <param name="use_gui" value="true"/>    
        <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" />
        <node name="rviz" pkg="rviz" type="rviz" />
    </launch>
    

    这里值得注意的是joint_state_publisher 和 robot_state_publisher
    前者用于发布joint_state信息,大概长这样:
    Header header
    string[] name
    float64[] position
    float64[] velocity
    float64[] effort
    http://docs.ros.org/melodic/api/sensor_msgs/html/msg/JointState.html
    现阶段我们在arduino中订阅joint_state这个话题就能获得上面这些信息,比如我们可以将位于"0"的舵机旋转到msg.position[0]的位置。

    当初在YouTube上看到了这个视频


    https://youtu.be/6OjYXSEfVJ4

    问了作者之后发现原来只要订阅joint_state就行了。现在我们稍微修改一下ros_lib里控制舵机的示例代码来测试一下这个想法。

    #if (ARDUINO >= 100)
     #include <Arduino.h>
    #else
     #include <WProgram.h>
    #endif
    
    #include <Servo.h>
    #include <ros.h>
    #include <std_msgs/UInt16.h>
    #include <sensor_msgs/JointState.h>
    ros::NodeHandle  nh;
    //float pos=0;
    Servo servo;
    void servo_cb(const sensor_msgs::JointState& msg)
    {
      float pos=msg.position[0];
        servo.write(90-pos*57.3248);
    }
    ros::Subscriber<sensor_msgs::JointState> sub("joint_states",servo_cb);
    
    
    void setup(){
      //Serial.begin(57600);
      nh.initNode();
      nh.subscribe(sub);
      servo.attach(9); //attach it to pin 9
    }
    
    void loop(){
      nh.spinOnce();
    
      delay(1);
    }
    

    于此同时,在launch文件里启动joint_state_publisher之外还要设置参数

     <param name="use_gui" value="true"/>    
    

    这样运行的时候就会有GUI你可以用上面的slider来控制之前在joint->limit里设置的角度,这里是从-1.57到1.57,原因是它是一个180度的舵机。
    然后我们使用刚刚的launch文件进入rviz


    DISPLAY

    首先把Fixed Frame设置成我们的base_link,然后添加RobotModel,其中Robot Description就是我们刚刚写的urdf。
    滑动刚刚那个slider的话就可以让上面这个红色的配件沿着事先设定好的轴旋转,这个在urdf的joint中设定。
    值得一提的是每个link还有joint都有

     <origin rpy="0 0 0" xyz="0 0 0" />
    

    child link的origin实际上是相对于它的parent link的,如果发生了问题,比如上面的配件转的莫名奇妙的,那可能是joint的origin和axis没有设置好,这点在从solidworks导出的时候也有可能出现(老年痴呆),所以掌握了手写urdf的技巧的话就不用重新导出好几遍了。

    现在,无论是rviz里的3d模型还是现实中的sg90舵机都订阅了joint_states,它们会同步旋转。
    https://www.bilibili.com/video/av34229434/

    下一篇可能是讲如何使用sw2urdf,直接从solidworks里导出urdf文件(我反正是不想手写,xacro也不想写)


    solidworks

    相关文章

      网友评论

        本文标题:从零开始的ROS机械臂,边做边学02-URDF篇

        本文链接:https://www.haomeiwen.com/subject/zgrmzftx.html