ROS学习记录12SLAM仿真学习1——ROS Control

Posted 康娜喵

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ROS学习记录12SLAM仿真学习1——ROS Control相关的知识,希望对你有一定的参考价值。

零.前言

学完了ROS的基础应用,我们就可以开始向更复杂的应用开始学习了,比如我们的SLAM。但是昂贵的底盘与激光雷达是学习这一部分的阻碍,为了弥补经费的不足,我们可以从0开始,创建一个自己的仿真小车,然后实现SLAM过程。最后真的有幸用到激光雷达和机器人底盘,那么直接移植写好的内容就可以了.
本次实验的平台为ubuntu 20.04 + ros/noetic,无特殊说明,后面的教程都为这个。
后面会把整个项目打包上传至github上,地址待定,写完再改。

一.什么是ros_control

该ros_control包是一个重写pr2_mechanism包,使控制器通用的并不仅止于PR2所有机器人。
它是介于你的机器人硬件代码以及各种定位导航的一个中间件。
你可以自己编写节点将下位机的数据传输至上位机并自己处理数据并进行控制。当然也可以交给ros_control去处理。当然ros_control除了将数据处理成我们定位导航包的需求以外,同时还会传递至Gazebo仿真环境中。这里我就尝试边学边做一个简单的Demo,去实现一下简单的ros_control。
你可以理解为:

它的结构是这样的:

其官网地址:https://wiki.ros.org/ros_control#Examples

二.创建工作空间与包

先安装ros_control:

sudo apt-get install ros-noetic-ros-control ros-noetic-ros-controllers ros-noetic-velocity-controllers ros-noetic-view-controller-msgs

在工作空间下创建一个SLAM的模型包:
假设先拥有这些包,后面不够的话再添加:std_msgs roscpp rospy controller_manager joint_state_controller robot_state_publisher

catkin_create_pkg slam_model std_msgs roscpp rospy controller_manager joint_state_controller robot_state_publisher

然后编译,修改环境变量:

source /home/kanna/ros_ws/devel/setup.bash

slam_model下创建urdflaunch文件夹,最后整个文件夹结构看起来因该是这样:

三.创建一个能旋转和能扭动的小机构

slam_model下创建一个nbmod.urdf
写入:

<robot name="nbmod">
    <link name="base_footprint">
        <visual>
        <origin rpy="0 0 0" xyz="0 0 0"/>
        <geometry>
            <box size="0.001 0.001 0.001"/>
        </geometry>
        </visual>
    </link>

    <joint name="base_footprint_joint" type="fixed">
        <origin rpy="0 0 0" xyz="0 0 0.5"/>
        <parent link="base_footprint"/>
        <child link="base_link"/>
    </joint>

    <link name="base_link">
        <inertial>
            <origin xyz="0 0 0"/>
            <mass value="1.0"/>
            <inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>
        </inertial>
        <visual>
            <geometry>
                <box size="1 1 1"/>
            </geometry>
            <origin rpy="0 0 0" xyz="0 0 0"/>
            <material name="blue">
                <color rgba="0 0 0.8 1"/>
            </material>
        </visual>
        <collision>
            <origin rpy="0 0 0" xyz="0 0 0"/>
            <geometry>
                <box size="1 1 1"/>
            </geometry>
            <inertial>
                <mass value="20"/>
                <inertia ixx="0.00533333333333" ixy="0" ixz="0" iyy="0.00833333333333" iyz="0" izz="0.0666666666667"/>
            </inertial>
        </collision>
    </link>

    <joint name="joint_base2lidar" type="continuous">
        <axis xyz="0 0 1"/>
        <parent link="base_link"/>
        <child link="lidar"/>
        <origin rpy="0 0 0" xyz="0 0 0.75"/>
        <limit effort="100" velocity="100"/>
        <joint_properties damping="0.0" friction="0.0"/>
    </joint>

    <link name="lidar">
    <inertial>
        <origin xyz="0 0 0"/>
        <mass value="0.1"/>
        <inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>
    </inertial>
    <visual>
        <geometry>
            <cylinder length="0.5" radius="0.25"/>
        </geometry>
        <material name="black">
            <color rgba="0 0 0 1"/>
        </material>
    </visual>
    <collision>
        <origin rpy="0 0 0" xyz="0 0 0"/>
        <geometry>
            <cylinder length="0.5" radius="0.25"/>
        </geometry>
        <inertial>
            <mass value="1"/>
            <inertia ixx="0.000379166666667" ixy="0" ixz="0" iyy="0.000379166666667" iyz="0" izz="0.000625"/>
        </inertial>
    </collision>
    </link>

    <joint name="axle_lidar2barrel" type="revolute">
        <parent link="lidar"/>
        <child link="barrel"/>
        <origin rpy="0 -1.57 0" xyz="-0.25 0 0.25"/>
        <axis xyz="0 1 0"/>
        <limit effort="2.5" lower="0" upper="0.785" velocity="0.1"/>
    </joint>

    <link name="barrel">
        <inertial>
            <origin xyz="0 0 0.25"/>
            <mass value="0.1"/>
            <inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>
        </inertial>
        <visual>
            <origin rpy="0 0 0" xyz="0 0 0.25"/>
            <geometry>
                <cylinder length="0.5" radius="0.01"/>
            </geometry>
            <material name="black">
                <color rgba="0 0 0 1"/>
            </material>
        </visual>
        <collision>
            <origin rpy="0 0 0" xyz="0 0 0.25"/>
            <geometry>
                <cylinder length="0.5" radius="0.01"/>
            </geometry>
            <inertial>
                <mass value="0.5"/>
                <inertia ixx="0.000379166666667" ixy="0" ixz="0" iyy="0.000379166666667" iyz="0" izz="0.000625"/>
            </inertial>
        </collision>
    </link>

    <gazebo reference="base_link">
        <material>Gazebo/White</material>
    </gazebo>
    <gazebo reference="lidar">
        <material>Gazebo/Blue</material>
    </gazebo>
    <gazebo reference="barrel">
        <material>Gazebo/Red</material>
    </gazebo>
</robot>

这样就做好了一个简易的坦克。现在编写launchrvizgazebo里看看效果

<launch>
    <include file="$(find gazebo_ros)/launch/empty_world.launch"></include>
    <param name="robot_description" textfile="$(find slam_model)/urdf/nbmod.urdf" />
    <param name="use_gui" value="true"/>
    <node name="joint_state_publisher" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" />
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
    <node name="rviz" pkg="rviz" type="rviz" args="-d $(find slam_model)/urdf/config.rviz" required="true"></node>
    <node name="spawn_model" pkg="gazebo_ros" type="spawn_model" args="-file $(find slam_model)/urdf/nbmod.urdf -urdf -model nbmod" output="screen"/>
</launch>

在配置好rviz的可视化参数后,我们可以移动某些关节,在rviz里看到效果,可是gazebo纹丝不动。
这时候我们的话题关系是这样的:

那么我们就要请出ros_control插件进行指令的转义了,将joint_states等话题发布给gazebo

四.ROS Control

4.1 认识Gazebo ROS Control Plugin

Gazebo ROS Control Plugin这个继承于gazebo::ModelPlugin类,也是我们仿真时用的插件。最主要的还是编写ROS Controller。其源码地址:https://github.com/ros-simulation/gazebo_ros_pkgs
我们最主要的是控制某些关节的位置,那么就会用到这个JointPositionControllerJointGroupPositionController二者的区别就是:注册一个控制器,是控制一个joint还是多个joint
以及,我们所有关节的tf关系是由/namespace/joint_states这个话题所发布的。

4.2 在URDF里注册插件

首先在我们nbmod.urdf里面添加我们的transmission,官方说明地址:http://wiki.ros.org/urdf/XML/Transmission
添加两个transmission

    <transmission name="tran_lidar">
        <type>transmission_interface/SimpleTransmission</type>
        <joint name="joint_base2lidar">
            <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
        </joint>
        <actuator name="motor1">
            <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
            <mechanicalReduction>1</mechanicalReduction>
        </actuator>
    </transmission>

    <transmission name="tran_barrel">
        <type>transmission_interface/SimpleTransmission</type>
        <joint name="axle_lidar2barrel">
            <hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
        </joint>
        <actuator name="motor2">
            <hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
            <mechanicalReduction>1</mechanicalReduction>
        </actuator>
    </transmission>

    <gazebo>
        <plugin filename="libgazebo_ros_control.so" name="ros_control">
            <robotNamespace>/nbmod以上是关于ROS学习记录12SLAM仿真学习1——ROS Control的主要内容,如果未能解决你的问题,请参考以下文章

ROS学习记录17SLAM仿真学习6完结—— 无人驾驶

ROS学习记录17SLAM仿真学习6完结—— 无人驾驶

ROS学习记录13SLAM仿真学习2——创建一个包含LidarCameraIMU的Ackman小车

ROS学习记录13SLAM仿真学习2——创建一个包含LidarCameraIMU的Ackman小车

ROS学习记录14SLAM仿真学习3——开车,并发布坐标信息

ROS学习记录14SLAM仿真学习3——开车,并发布坐标信息