第 2 章 ROS 通信机制 6 —— 通信机制实操 2 plumbing_test

01 服务调用 plumbing_test

1.0 需求 - 分析 - 流程

  • 需求描述:编码实现向 turtlesim 发送请求,在乌龟显示节点的窗体指定位置生成一乌龟,这是一个服务请求操作。

实现分析:

  1. 首先,需要启动乌龟显示节点。
  2. 要通过ROS命令,来获取乌龟生成服务的服务名称以及服务消息类型。
  3. 编写服务请求节点,生成新的乌龟。

实现流程:

  1. 通过ros命令获取服务与服务消息信息。
  2. 编码实现服务请求节点。
  3. 启动 roscore、turtlesim_node 、乌龟生成节点,生成新的乌龟。

1.1 服务名称与服务消息获取

1.1.0 启动控制乌龟运动节点(获得话题和消息) start_turtle.launch

<!-- 启动乌龟GUI与键盘控制节点-->
<launch>
    <!-- 乌龟GUI-->
    <!-- pkg——包,type——被执行的节点,name——节点取的名字,output = "screen"——日志输出到屏幕上-->
    <!-- rosrun turtlesim(pkg)功能包 turtlrsim_node(type)-->
    <node pkg = "turtlesim" type = "turtlesim_node" name = "turtle1" output = "screen"/> 
    <!-- 键盘控制-->
    <node pkg = "turtlesim" type = "turtle_teleop_key" name = "key" output = "screen" /> 
</launch>
1.1.0.0 vscode终端启动 launch 文件
cd demo01_ws 
source ./devel/setup.bash 
roslaunch plumbing_test start_turtle.launch

1.1.1 获取话题 /spawn(产卵) (addInts)

  • 在终端ternimal新建窗口
  • rosservice list (不是rostopic)

/clear
/key/get_loggers
/key/set_logger_level
/kill
/reset
/rosout/get_loggers
/rosout/set_logger_level
/spawn
/turtle1/get_loggers
/turtle1/set_logger_level
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative

在这里插入图片描述

1.1.2 获取服务消息类型 turtlesim/Spawn (AddInts.srv)

  • rosservice info /spawn:获取 turtlesim/Spawn

Node: /turtle1
URI: rosrpc://rosnoetic-VirtualBox:60831
Type: turtlesim/Spawn
Args: x y theta name

在这里插入图片描述

1.1.3 获取服务消息格式

  • theta是弧度制,范围是3.14rad——(-3.14)rad,逆时针为正,顺时针为负
  • rossrv info turtlesim/Spawn
  • 说明:x与y是乌龟的坐标,theta是乌龟的朝向,name是乌龟的名字

float32 x (上半部分是请求)
float32 y
float32 theta
string name


string name(下半部分是响应)

在这里插入图片描述

1.2 实现服务客户端 —— plumbing_test

1.2.1 C++实现 —— test03_server_client.cpp

#include"ros/ros.h"
#include"turtlesim/Spawn.h"

/*
    需求:向服务器发送请求,生成一个新的乌龟
        话题:/spawn
        消息:turtlesim/Spawn
    
    1.包含头文件
    2.初始化ROS节点
    3.创建节点句柄
    4.创建客户端对象
    5.组织数据并发送
    6.处理响应
*/

int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");

    // 2.初始化ROS节点
    ros::init(argc,argv,"service_call");

    // 3.创建节点句柄
    ros::NodeHandle nh;

    // 4.创建客户端对象
    ros::ServiceClient client = nh.serviceClient<turtlesim::Spawn>("/spawn"); // /spawn是话题名称

    // 5.组织数据并发送
    // 5.1 组织请求数据
    turtlesim::Spawn spawn;
    spawn.request.x = 1.0;
    spawn.request.y = 4.0;
    spawn.request.theta = 4.0;
    spawn.request.name = "turtle2";

    // 5.2 发送请求
    //判断服务器状态
    // ros::service::waitForService("/spawn");
    client.waitForExistence();
    bool flag = client.call(spawn);//flag 接受响应状态,响应结果也会被设置进spawn对象
    
    // 6.处理响应
    if(flag) // 响应成功
    {
        ROS_INFO("乌龟生成成功,新乌龟叫:%s",spawn.response.name.c_str());
    }
    else
    {
        ROS_INFO("请求失败!!!");
    }

    return 0;
}

1.2.2 配置 CMakeLists.txt

add_executable(test03_server_client src/test03_server_client.cpp)

add_dependencies(test03_server_client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) —— 可以不添加,因为没有自定义消息

target_link_libraries(test03_server_client
  ${catkin_LIBRARIES}
)

1.2.3 编译运行

  • 编译:Ctrl + Shift + B
  • 启动 launch vscode终端窗口 —— 要把光标放在vscode终端启动launch文件的位置!!!
source ./devel/setup.bash
roslaunch plumbing_test start_turtle.launch
  • ctrl+alt+t:开新的窗口

  • 启动 roscore(窗口1)

roscore
  • 启动客户端(窗口2)
cd demo01_ws
source ./devel/setup.bash
rosrun plumbing_test test03_service_client

1.2.4 Python实现 —— test03_server_client_p.py

#! /usr/bin/env python


"""
    需求:向服务器发送请求生成一个乌龟
        话题:/spawn
        消息类型:turtlesim/Spawn
    1. 导包
    2. 初始化ROS节点
    3. 创建服务的客户端对象
    4. 组织数据并发送请求
    5. 处理响应结果

"""

import rospy
from turtlesim.srv import Spawn,SpawnRequest,SpawnResponse

if __name__ == "__main__":
    # 2. 初始化ROS节点
    rospy.init_node("service_call")
    # 3. 创建服务的客户端对象
    client = rospy.ServiceProxy("/spawn",Spawn) # /spawn是话题名称
    # 4. 组织数据并发送请求
    # 4.1 组织数据
    request = SpawnRequest()
    request.x = 4.5
    request.y = 2.0
    request.theta = -3 # 向右转3个rad
    request.name = "turtle3"
    # 4.2 判断服务器状态并发送
    client.wait_for_service() # 服务端开启则执行,否则挂起
    # 防止抛出异常
    try:
        response = client.call(request)
        # 5. 处理响应结果
        rospy.loginfo("生成乌龟的名字叫:%s",response.name)
    except Exception as e:
        rospy.logerr("请求处理异常")

1.2.5 添加可执行权限

scripts文件右击,在终端中打开
终端下进入 scripts 执行

chmod +x *.py
ll

1.2.6 配置 CMakeLists.txt

catkin_install_python(PROGRAMS
  scripts/test03_server_client_p.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

1.2.7 编译运行

  • 编译:Ctrl + Shift + B
  • 启动 launch vscode终端窗口 —— 要把光标放在vscode终端启动launch文件的位置!!!
source ./devel/setup.bash
roslaunch plumbing_test start_turtle.launch
  • ctrl+alt+t:开新的窗口

  • 启动 roscore(窗口1)

roscore
  • ctrl+alt+t:开新窗口
  • 启动客户端(窗口2)
cd demo01_ws
source ./devel/setup.bash
rosrun plumbing_test test03_server_client_p.py

02 参数设置 plumbing_test

2.0 需求 - 分析 - 流程

  • 需求描述:修改turtlesim乌龟显示节点窗体的背景色,已知背景色是通过参数服务器的方式以 rgb 方式设置的。

实现分析:

  1. 首先,需要启动乌龟显示节点。
  2. 要通过ROS命令,来获取参数服务器中设置背景色的参数。
  3. 编写参数设置节点,修改参数服务器中的参数值。

实现流程:

  1. 通过ros命令获取参数。
  2. 编码实现服参数设置节点。
  3. 启动 roscore、turtlesim_node 与参数设置节点,查看运行结果。

2.1 参数名获取

2.1.0 启动键盘控制乌龟运动(获得话题和消息,没有用launch文件)

  • 窗口1
roscore
  • 窗口2
rosrun turtlesim turtlesim_node

在这里插入图片描述

2.1.1 获取参数列表

  • 窗口3:获取参数列表rosparam list

/rosdistro
/roslaunch/uris/host_rosnoetic_virtualbox__43129
/rosversion
/run_id
/turtlesim/background_b
/turtlesim/background_g
/turtlesim/background_r

在这里插入图片描述

  • 获取参数值rosparam get /turtlesim/background_r/b/g

在这里插入图片描述

  • 使用命令方式修改颜色 rosparam set /turtlesim/background_r 255,然后重新启动节点 rosrun turtlesim turtlesim_node 就可以修改成功

2.2 实现参数修改

2.2.1 C++实现 —— test04_param.cpp

#include"ros/ros.h"

/*
    需求:修改参数服务器中turtlesim背景色相关参数

    1.初始化ROS节点
    2.不一定需要创建节点句柄(和后续API有关)
    3.修改参数
*/


int main(int argc, char *argv[])
{
    // 1.初始化ROS节点
    ros::init(argc,argv,"change_bgcolor");
    // 2.不一定需要创建节点句柄(和后续API有关)
    // ros::NodeHandle nh("turtlesim");//设置命名空间
    // nh.setParam("background_r",255);
    // nh.setParam("background_g",255);
    // nh.setParam("background_b",255);

    ros::NodeHandle nh;
    nh.setParam("/turtlesim/background_r",0);
    nh.setParam("/turtlesim/background_g",50);
    nh.setParam("/turtlesim/background_b",100);

    // 3.修改参数
    // 方式1:如果调用ros::param 不需要创建节点句柄
    // ros::param::set("/turtlesim/background_r",0);
    // ros::param::set("/turtlesim/background_g",0);
    // ros::param::set("/turtlesim/background_b",0);

    // 方式2:使用nodehandle
    return 0;
}

2.2.2 配置 CMakeLists.txt

add_executable(test04_param src/test04_param.cpp)

add_dependencies(test04_param ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(test04_param
  ${catkin_LIBRARIES}
)

2.2.3 编译运行(不用启动launch文件)

  • 编译:Ctrl + Shift + B

  • 启动 roscore(窗口1)

roscore
  • 启动参数服务器(窗口2) 先不用 rosrun turtlesim turtlesim_node
cd demo01_ws
source ./devel/setup.bash
rosrun plumbing_test test04_param
  • 启动窗口3
rosrun turtlesim turtlesim_node(最后启动)

2.2.4 Python实现 —— test04_param_p.py

#! /usr/bin/env python
"""
    需求:修改乌龟GUI的背景色

    1.初始化ros节点
    2.设置参数
"""

import rospy

if __name__ == "__main__":
    rospy.init_node("change_bgcolor")

    # 修改背景色
    rospy.set_param("/turtlesim/background_r",100)
    rospy.set_param("/turtlesim/background_g",50)
    rospy.set_param("/turtlesim/background_b",200)

2.2.5 添加可执行权限

scripts文件右击,在终端中打开
终端下进入 scripts 执行

chmod +x *.py
ll

2.2.6 配置 CMakeLists.txt

catkin_install_python(PROGRAMS
  scripts/test04_param_p.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

2.2.7 编译运行(不启动launch文件)

  • 编译:Ctrl + Shift + B

  • 启动 roscore(窗口1)

roscore
  • ctrl+alt+t:开新窗口
  • 启动参数服务器(窗口2) 先不用 rosrun turtlesim turtlesim_node
cd demo01_ws
source ./devel/setup.bash
rosrun plumbing_test test04_param_p.py
  • 启动窗口3
rosrun turtlesim turtlesim_node(最后启动)

03 通信机制比较

三种通信机制中,参数服务器是一种数据共享机制,可以在不同的节点之间共享数据,话题通信与服务通信是在不同的节点之间传递数据的,三者是ROS中最基础也是应用最为广泛的通信机制。

这其中,话题通信和服务通信有一定的相似性也有本质上的差异,在此将二者做一下简单比较:

二者的实现流程是比较相似的,都是涉及到四个要素:

  • 要素1:消息的发布方/客户端(Publisher/Client)
  • 要素2:消息的订阅方/服务端(Subscriber/Server)
  • 要素3:话题名称(Topic/Service)
  • 要素4:数据载体(msg/srv)

概括为: 两个节点通过话题关联到一起,并使用某种类型的数据载体实现数据传输

二者的实现也是有本质差异的,具体比较如下:

Topic(话题)Service(服务)
通信模式发布/订阅请求/响应
同步性异步同步
底层协议ROSTCP/ROSUDPROSTCP/ROSUDP
缓冲区
时时性
节点关系多对多一对多(一个 Server)
通信数据msgsrv
使用场景连续高频的数据发布与接收:雷达、里程计偶尔调用或执行某一项特定功能:拍照、语音识别
  • 不同通信机制有一定的互补性,都有各自适应的应用场景。尤其是话题与服务通信,需要结合具体的应用场景与二者的差异,选择合适的通信机制
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2021 Nqq

你的鼓励是我学习的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值