ROS1重温:ROS程序的编写与使用


前言

在对 ROS 有一定了解后,大多情况下,大家都会有一定的迷茫:
① 这一个一个的字我都看懂了,但我该怎么用他呢?
② 如果是别人开发的 ROS 程序,又该怎么使用呢?


总体步骤

主要采用三个步骤:What(做什么)、Which(用什么)、How(怎么干)

第一步:What(做什么)

自己开发的:

  • 首先需要明确最终实现结果,即使无法估计全貌,也要明确一个总体开发方向。

他人开发的:

  • 在获取代码后,可以看包中的 README.md 文件,开发者一般会说明程序开发目的,以及程序的使用方法;
  • 当 README.md 文件中未提及任何有用信息时,可以按如下步骤启动程序:
    • 若存在 launch 文件,则在包文件处于工作空间中的前提下,直接roslaunch launch文件名
    • 若不存在 launch 文件,则查看 CMakeLists.txt 文件中的 add_executable() 项,该项括号中包含两个参数:编译生成的可执行文件名称(即节点名称),所要编译的源文件。最后在工作空间的更目录下执行rosnode 包名 节点名
      有几个节点,启动几个,尝试着去运行各个节点
  • 当然还有一点就是读代码,这是最直接、最彻底的,当然也是最耗时的,尤其是无注释的情况下;
  • 最后根据已知信息得出开发方向。

第二步:Which(用什么)

自己开发的:

  • 在明确大方向后,要考虑在开发过程中会涉及到哪些数据;
  • 对应的设计一个个数据结构,即每个所设计到对象的属性,及其所要用到的变量类型。

他人开发的:

  • 在相关程序运行之后,通过以下方式获取节点间关系、各种服务信息:

    • 运行命令:rqt_graph,获取节点间关系;
    • 运行命令:rosnode list,获取所有节点名称;
    • 运行命令:rostopic list,获取所有话题名称;
    • 运行命令:rosservice list,获取所有服务名称;
    • 运行命令:rosparam list,获取所有参数名称,运行命令:rosparam get 参数名称,获取特定参数值。
  • 在获取到节点名、话题名、服务名、参数名后,运行以下命令,在输出中Type项即为节点所用数据类型

    • 运行命令:rosnode info 节点名,获取特定节点信息
    • 运行命令:rostopic info 话题名称,获取特定话题信息
    • 运行命令:rosservice info 服务名称,获取特定服务信息。
  • 通过以下方式获取具体的数据结构:

    • 运行命令:rosmsg show 消息名称,获取特定消息的具体数据结构信息
    • 运行命令:rossrv show 服务名称,获取特定服务的具体数据结构信息

第三步:How(怎么干)

  • 根据第二步获取到的信息,并结合第一步得出的开发方向,总结得出适宜的通信方式,代码总体结构框架,最后补全适宜的算法完成整个 ROS 程序的开发。

实例展示

  • 以经典案例小乌龟的运动来完成本次实例展示。

原始小乌龟程序的运作机理

  • 原始的小乌龟案例是:创建一个小乌龟节点,创建一个小乌龟手动运动控制节点,最后人为手控运动。

原始小乌龟运作涉及到的具体事项

  • 运用 上面 第二步:Which(用什么) 提到的方法,获得以下信息:
    • 主要存在两个节点:
      /teleop_turtle
      /turtlesim
    • 主要存在三个话题:
      /turtle1/cmd_vel
      /turtle1/color_sensor
      /turtle1/pose
    • 主要存在七个服务:
      /clear:清除小乌龟行走轨迹
      /kill:杀死一个小乌龟
      /reset:重置 /turtlesim 节点
      /spawn:生成一只新的小乌龟
      /turtle1/set_pen:设置小乌龟运动轨迹形态
      /turtle1/teleport_absolute:设置小乌龟的绝对位姿
      /turtle1/teleport_relative:设置小乌龟的相对位姿
    • 主要存在三个参数:
      /turtlesim/background_b
      /turtlesim/background_g
      /turtlesim/background_r

新小乌龟程序改进需求

  • 现对这一案例进行改进,具体需求如下:
    • 需求1:发布话题——小乌龟自动转圈
    • 需求2:订阅话题——接收小乌龟位姿
    • 需求3:发布请求——创建一个新的小乌龟
    • 需求4:修改参数值——修改小乌龟所处环境的背景色

具体实现

添加依赖项

  • 修改 package.xml 文件:在文件加入依赖 turtlesim
  <build_depend>turtlesim</build_depend>
  <exec_depend>turtlesim</exec_depend>
  • 修改 CMakeLists.txt 文件:在 find_package() 中添加 turtlesim
find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  roscpp
  rospy
  std_msgs
  turtlesim
)

需求1:发布话题——小乌龟自动转圈

  • 创建 ROS C++文件:pub_twist.cpp
#include "ros/ros.h"
#include <geometry_msgs/Twist.h>


int main(int argc, char *argv[])
{
    // 设置中文编码
    setlocale(LC_ALL, "");
    // 初始化 ROS 节点
    ros::init(argc, argv, "turtle_twist");
    // 创建节点句柄
    ros::NodeHandle nh;
    // 创建发布者
    ros::Publisher pub = nh.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);

    // 设置运动速率
    geometry_msgs::Twist twist;
    twist.linear.x = 1.0;
    // twist.linear.y = 0.0;
    // twist.linear.z = 0.0;
    // twist.angular.x = 0.0;
    // twist.angular.y = 0.0;
    twist.angular.z = 1.5;

    // 设置发布评率
    ros::Rate rate(10);
    while(ros::ok())
    {
        pub.publish(twist);
        // 休眠以控制频率
        rate.sleep();
        // ros::spinOnce();
    }

    return 0;
}
  • 修改- 修改 CMakeLists.txt 文件:
add_executable(turtle_twist_node src/pub_twist.cpp)

target_link_libraries(turtle_twist_node
  ${catkin_LIBRARIES}
)

需求2:订阅话题——接收小乌龟位姿

  • 创建 ROS C++文件:pub_twist.cpp
#include "ros/ros.h"
#include <turtlesim/Pose.h>

void getPose(const turtlesim::Pose::ConstPtr &pose)
{
    ROS_INFO("小乌龟位姿信息:坐标 ( %.2f, %.2f ),朝向:%.2f, 线速度:%.2f,角速度:%.2f",
             pose->x, pose->y, pose->theta, pose->linear_velocity, pose->angular_velocity);
}

int main(int argc, char *argv[])
{
    // 设置中文编码
    setlocale(LC_ALL, "");
    // ros 初始化
    ros::init(argc, argv, "sub_pose_node");
    // ros 句柄初始化
    ros::NodeHandle nh;
    // 创建订阅者
    ros::Subscriber sub = nh.subscribe("/turtle1/pose", 10, getPose);
    // // 不断调用回调函数,保证一直订阅
    // ros::spin();

    // 设置订阅频率
    ros::Rate rate(1);
    // 开始订阅
    while (ros::ok())
    {
        rate.sleep();
        ros::spinOnce();
    }

    return 0;
}
  • 修改- 修改 CMakeLists.txt 文件:
add_executable(sub_pose_node src/sub_pose.cpp)

target_link_libraries(sub_pose_node
  ${catkin_LIBRARIES}
)

需求3:发布请求——创建一个新的小乌龟

  • 创建 ROS C++文件:pub_twist.cpp
#include "ros/ros.h"
#include <turtlesim/Spawn.h>


int main(int argc, char *argv[])
{
    // 设置中文编码
    setlocale(LC_ALL, "");
    // ROS 初始化
    ros::init(argc, argv, "new_turtle_node");
    // ROS 句柄创建
    ros::NodeHandle nh;
    // 创建客户端对象
    ros::ServiceClient client = nh.serviceClient<turtlesim::Spawn>("/spawn");
    // 创建请求数据载体
    turtlesim::Spawn spawn;

    // 设置小乌龟坐标参数
    spawn.request.name = "new_turtle1";
    spawn.request.theta = 1.57;
    spawn.request.x = 1.0;
    spawn.request.y = 5.0;

    // 判断服务器状态
    // ros::service::waitForService("/spawn");
    client.waitForExistence();
    // 发送 spawn
    bool flag_call = client.call(spawn);
    // 处理申请姐夫哦
    if(flag_call)
    {
        ROS_INFO("小乌龟 %s 生成成功!", spawn.response.name.c_str());
    }
    else
    {
        ROS_INFO("小乌龟生成失败!");
    }

    return 0;
}
  • 修改- 修改 CMakeLists.txt 文件:
add_executable(new_turtle_node src/client_new_turtle.cpp)

target_link_libraries(new_turtle_node
  ${catkin_LIBRARIES}
)

需求4:修改参数值——修改小乌龟所处环境的背景色

  • 创建 ROS C++文件:pub_twist.cpp
#include "ros/ros.h"


int main(int argc, char *argv[])
{
    // 设置中文编码
    setlocale(LC_ALL, "");
    // ROS 初始化
    ros::init(argc, argv, "bg_color_node");

    // 修改背景颜色参数
    // 方法一:ros::param::set
    // ros::param::set("/turtlesim/background_r", 0);
    // ros::param::set("/turtlesim/background_g", 255);
    // ros::param::set("/turtlesim/background_b", 0);

    // 方法二:ros::NodeHandle
    // ROS 句柄创建
    ros::NodeHandle nh("turtlesim");    // 附加命名空间,即参数主地址,之后可以简略代码
    nh.setParam("background_r", 0);
    nh.setParam("background_g", 0);
    nh.setParam("background_b", 255);


    return 0;
}
  • 修改- 修改 CMakeLists.txt 文件:
add_executable(bg_color_node src/param_new_bg_color.cpp)

target_link_libraries(bg_color_node
  ${catkin_LIBRARIES}
)
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值