1 创建一个package
<code class="has-numbering">catkin_create_pkg myurdf joint_state_controller robot_state_publisher roscpp std_msgs tf </code>
2 创建urdf文件夹
<code class="has-numbering">cd myurdf mkdir urdf </code>
3 创建urdf文件
<code class="has-numbering">gedit myfirstrobot.urdf </code>
输入以下内容,并保存:
<code class="has-numbering"><?xml version="1.0"?> <robot name="myfirstrobot"> <!-- Base Link --> <link name="base_link"> <visual> <geometry> <box size="0.1 0.1 2"/> </geometry> </visual> </link> </robot> </code>
4 创建launch文件
<code class="has-numbering">cd myurdf mkdir launch gedit display.launch </code>
输入并保存以下内容:
<code class="has-numbering"><launch> <param name="robot_description" textfile="$(find myurdf)/urdf/myfirstrobot.urdf"/> <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher"/> <node name="rviz" pkg="rviz" type="rviz" respawn="false" output="screen"/> </launch> </code>
5 启动launch文件
<code class="has-numbering">roslaunch myurdf display.launch </code>
得到下图结果:
6 增加一个连杆 更新后的urdf文件如下:
<code class="has-numbering"><?xml version="1.0"?> <robot name="myfirstrobot"> <!-- Base Link --> <link name="base_link"> <visual> <geometry> <box size="0.1 0.1 2"/> </geometry> </visual> </link> <joint name="joint1" type="continuous"> <parent link="base_link"/> <child link="middle_link"/> <origin rpy="0 0 0" xyz="0 0 1"/> <axis xyz="0 1 0"/> </joint> <link name="middle_link"> <visual> <geometry> <box size="0.2 0.2 1"/> </geometry> </visual> </link> </robot> </code>
得到下图结果:
发现问题: (1) Global Status: WARN状态,显示信息为No tf data. Actual error: Fixed Frame [base_link] does not exist. (2) 在TF显示控件中,并没优tf tree存在,由于此时机器人模型由两个杆件组成,因此tf tree 应包含 base_link 和 middle_link. 问题原因: urdf文件中,joint type=“continuous”,说名该joint为旋转型。对于旋转型关节,必须给出robot_state_publisher 节点所需的sensor_msgs/JointState型topic :joint_states。可参见:robot_state_publisher 解决方案: 以任意方式发布sensor_msgs/JointState型topic :joint_states。 7 以下是自定义节点发布joint_states 创建state_publisher.cpp
<code class="has-numbering">#include <string> #include <ros/ros.h> #include <sensor_msgs/JointState.h> int main(int argc, char** argv) { ros::init(argc, argv, "state_publisher"); ros::NodeHandle n; ros::Publisher joint_pub = n.advertise<sensor_msgs::JointState>("joint_states", 1); ros::Rate loop_rate(30); const double degree = M_PI/180; // robot state double tilt = 0, tinc = degree, swivel=0, angle=0, height=0, hinc=0.005; // message declarations sensor_msgs::JointState joint_state; while (ros::ok()) { //update joint_state joint_state.header.stamp = ros::Time::now(); joint_state.name.resize(3); joint_state.position.resize(3); joint_state.name[0] ="joint1"; joint_state.position[0] = swivel; joint_pub.publish(joint_state); // This will adjust as needed per iteration loop_rate.sleep(); } return 0; }; </code>
正确配置CMakelists文件,在此不再赘述,完成后编译。 8 配置launch文件
<code class="has-numbering"><launch> <param name="robot_description" textfile="$(find myurdf)/urdf/myfirstrobot.urdf"/> <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher"/> <node name="state_publisher" pkg="myurdf" type="state_publisher"/> <node name="rviz" pkg="rviz" type="rviz" respawn="false" output="screen"/> </launch> </code>
8 再次启动launch文件
<code class="has-numbering">roslaunch myurdf display.launch </code>
得到如下结果:
发现: (1) Global Status:状态正常 (2) tf tree 中包含 base_link 和 middle_link (3) 显示窗口显示base_link和middle_link frame 还可以通过其他方式处理,如通过joint_state_publisher节点,相关处理可参考wiki。 至此,问题解决。 建模参考:https://blog.csdn.net/wxflamy/article/details/79235493