初学ROS总结

初步总结一下自己对ros的认识,遇到的坑以及相应的解决办法。

首先介绍一下我的电脑配置,win10系统,装虚拟机Ubuntu16.04,ros版本kinetic.

我的学习资料主要来源:创客智造网站,ros官网,mooc网上面的ros课程(有的时候自己会遗漏一些点,上面可以了解到)

第一步是Ubuntu的使用,如果不熟悉Ubuntu的话,可以去一个叫 实验楼的网站上学习Ubuntu的基本操作,命令。

第二部ros的安装,按照创客智造上面的操作步骤就可以完成安装了,但是使用过程中遇到了两个问题,都是和gazebo有关,

export SVGA_VGPU10=0
export LIBGL_ ALWAYS_SOFTWARE=0

加上第二行代码可以减小  coreDump发生的概率。

第三  使用的IDE是roboware,关于roboware的教程很多,但是有几个注意的点,

这个小按钮可以record topic.

这两个按钮可以切换活动包

这里可以安装包以及对没有安装的包进行安装。之前从github上面克隆的代码在本地一直编译不过去,很久找不到原因,后来才发现自己克隆错了,在git clone 的时候,加上-b 参数克隆正确的分支,我的就是 git clone -b branch  gitsource.

第四部分,ros的基本概念是运行单元是node,通过topic,service,actonlib等进行通信。

rviz只是ros的一个展示数据的一个工具,仅仅用来展示二维或者三维数据。

gazebo是一个仿真环境,用来模拟真实的环境。

学习ros一定想要创建一个模型,并且在ros中控制它。首先学习urdf来创建机器人模型,urdf主要包括两部分,一个是link(肢体),另外一个是joint(关节),link通过joint链接在一起,joint有一些固定的类型,不同的类型就不同的参数配置。这里需要注意的是link之间的相关位置计算。 每个link对应一个坐标系,不同的link的坐标系的转换通过joint,joint不仅定义了关节的类型,还有joint 的parent和children 之间的坐标系转换,  gazebo里面简单的shape存在固定的中心,link有一个origin属性,像这样

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

这个属性定义了关节在自己的坐标中的偏移和转向。r代表绕X轴旋转的弧度,p代表绕Y轴旋转的弧度,y代表绕Z轴旋转的弧度。

joint中也存在这个属性,

  <joint name="base_to_child" type="continuous">
    <parent link="base_link"/>
    <child link="child"/>
    <origin xyz="1 1 1"  rpy="0 0 0"  />
  </joint>

像这样。

rviz中存在一个插件叫robotModel,他会从 rosparams中获得robotdescption(urdf文本)参数,进行展示,并且监听不同link之间的tf转换消息,你可以启动joint_state_publisher,robot_state_publisher节点,他也会去读取robotdescption参数,然后展现出一个界面,来发布tf变换到rviz的robotModel插件中进行展示,rviz中就可以展示出相应的效果出来。

gazebo中渲染机器人并且控制它,

  <gazebo>
    <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
    </plugin>
  </gazebo>

模型中一定要存在这个插件,这件插件的作用官网上写的是链接ros和gazebo,



class GazeboRosControlPlugin : public gazebo::ModelPlugin
{
public:

  virtual ~GazeboRosControlPlugin();

  // Overloaded Gazebo entry point
  virtual void Load(gazebo::physics::ModelPtr parent, sdf::ElementPtr sdf);

  // Called by the world update start event
  void Update();

  // Called on world reset
  virtual void Reset();

  // Get the URDF XML from the parameter server
  std::string getURDF(std::string param_name) const;

  // Get Transmissions from the URDF
  bool parseTransmissionsFromURDF(const std::string& urdf_string);

 

这个是libgazebo_ros_control.so中插件的头文件,GazeboRosControlPlugin 是一个gazebo的model插件,可以看到gazebo和ros链接的过程是,gazebo启动gazebo插件:GazeboRosControlPlugin ,这个插件再负责其他的工作,比如说初始化controllermanager来管理不同的控制器,下面就是初始化控制器的代码。

robot_hw_sim_loader_.reset
      (new pluginlib::ClassLoader<gazebo_ros_control::RobotHWSim>
        ("gazebo_ros_control",
          "gazebo_ros_control::RobotHWSim"));

    robot_hw_sim_ = robot_hw_sim_loader_->createInstance(robot_hw_sim_type_str_);
    urdf::Model urdf_model;
    const urdf::Model *const urdf_model_ptr = urdf_model.initString(urdf_string) ? &urdf_model : NULL;

    if(!robot_hw_sim_->initSim(robot_ns, model_nh_, parent_model_, urdf_model_ptr, transmissions_))
    {
      ROS_FATAL_NAMED("gazebo_ros_control","Could not initialize robot simulation interface");
      return;
    }

    // Create the controller manager
    ROS_DEBUG_STREAM_NAMED("ros_control_plugin","Loading controller_manager");
    controller_manager_.reset
      (new controller_manager::ControllerManager(robot_hw_sim_.get(), model_nh_));

    // Listen to the update event. This event is broadcast every simulation iteration.
    update_connection_ =
      gazebo::event::Events::ConnectWorldUpdateBegin
      (boost::bind(&GazeboRosControlPlugin::Update, this));

关于控制器更新的细节,我也有待更加深入的学习,

控制gazebo中一个关节的过程是,首先有一个urdf文件,配置好关节的物理参数,配置好关节的transmission信息,

类似

<transmission name="trans_${linkName}">
    <type>transmission_interface/SimpleTransmission</type>
    <actuator name="actuator_${linkName}">
      <mechanicalReduction>1</mechanicalReduction>
    </actuator>
    <joint name="base_to_${linkName}">
      <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
    </joint>
  </transmission>

关节主要是配置hardwareInterface接口,接口类型主要有三种,力接口,速度接口,位置接口,分别控制关节的力,速度,位置。然后加载实现指定接口的控制器信息到ros的参数服务器中,gazebo节点就会监听相应关节的command话题,就可以发布参数到指定话题来达到控制关节的目的。

学会控制关节之后就是slam,建图算法订阅/scan话题等后发布map话题,表达算法建的图,move_base得到map信息,然后根据acml算法等进行定位,然后告诉move_base一个目标点,move_base就会构建一个通向目标的路径,并且发布控制速度和转向信息,根据速度,转向信息就可以达到设定的目标点了,大致过程就是这样的。

猜你喜欢

转载自blog.csdn.net/qq_22553301/article/details/85471620