ros使用时的注意事项&技巧2
1.查看参数列表 rosparam list
2.查询参数rosparam get parameter_name,如rosparam get /rosdistro
3.设置参数rosparam set parameter_name parameter_value
4.运行turtlesim_node节点,再查看参数列表rosparam list,我们看到
/background_b
/background_g
/background_r
三个参数,将/background_b 设置成255我们没看到变化,这是因为turtlesim_node节点没有加载参数,而加载参数需要运行rosservice call /clear
5.需要引起高度注意的是,更新的参数值不会自动“推送”到节点。恰恰相反,如果节点关心它的一些或者所有参数是否改变,必须明确向参数服务器请求这些参数的值。同样地,如果希望改变某个活跃节点的参数值,我们必须知道该节点如何或是否重新查询参数。
6.使用C++获取参数并赋值
void ros::param::set(parameter_name, input_value);
bool ros::param::get(parameter_name, output_value);
7.服务调用是双向的,一个节点给另一个节点发送信息并等待响应,因此信息流是双向的。作为对比,当消息发布后,并没有响应的概念,甚至不能保证系统内有节点订阅了这些消
息。
8.服务调用的基本流程:
一个客户端(client)节点发送一些称为请求(request)的数据到一个服务器(server)节点,并且等待回应。服务器节点接收到请求后,采取一些行动(计算、配置软件或硬件、改变
自身行为等),然后发送一些称为响应(response)的数据给客户端节点。
9.列出所有服务rosservice list
10.查看某个节点的服务类型 要查看一个特定节点提供的服务,使用 rosnode info 命令:rosnode info node-name,如rosnode info turtlesim
11.查找提供服务的节点rosservice node service-name
12.查找服务的数据类型 rosservice info service-name
13.查看服务数据类型 当服务的数据类型已知时,我们可以使用rossrv 指令来获得此服务数据类型的详情:rossrv show service-data-type-name
14.从命令行调用服务; 为了直观地观察服务是如何工作的,你可以使用下面这条指令,从命令行中调用它们:rosservice call service-name request-content 例如
rosservice call /spawn 3 3 0 Mikey 这条服务调用的效果是在现有仿真器中,位置 ( x , y ) = (3,3) 处创建一个名为“Mikey”的新海龟,其朝向角度 θ = 0 。
15.声明请求和响应的类型 就像消息类型一样每一种服务数据类型都对应一个我们必须包含的相关 C++头文件
16.创建客户端对象 ros::ServiceClient client = node_handle.serviceClient<service_type>(service_name);
这条指令有三个重要部分。
node_handle 是常用的 ros::NodeHandle 对象,这里我们将调用它的 serviceClient 方法。
service_type 是我们在上面头文件中定义的服务对象的数据类型,在本例中,类型为 turtlesim::Spawn。
service_name 是一个字符串,说明了我们想要调用的服务名称。再次强调,这应当是一个相对名称,虽然也可以声明为全局名称。例子中使用的是相对名称“spawn”。
17.创建请求和响应对象 一旦有了 ros::ServiceClient 实例,下一步就是创建一个请求对象来容纳送往服务器的数据。我们上面包含的头文件中分别定义了请求和响应的类 ,命名为Request和Response。这些类必须通过功能包名称和服务类型来引用,如下所示:
#include <ros/ros.h>
//The srv class for the service.
#include <turtlesim/Spawn.h>
int main(int argc, char** argv) {
ros::init(argc, argv,"spawn_turtle");
ros::NodeHandle nh ;
// Create a client object for the spawn service . This
// needs to know the data type of the service and its
// name.
ros::ServiceClient spawnClient = nh.serviceClient <turtlesim::Spawn>("spawn") ;
// Create the request and response objects.
turtlesim::Spawn::Request req ;
turtlesim::Spawn::Response resp ;
// Fill in the request data members.
req.x = 2;
req.y = 3;
req.theta = M_PI/2;
req.name = "Pik" ;
// Actually call the service. This won't return until
// the service is complete .
bool success = spawnClient.call(req, resp);
// Check for success and use the response .
if(success) {
ROS_INFO_STREAM("Spawned a turtle named "<< resp.name);
} else {
ROS_ERROR_STREAM("Failed to spawn.") ;
}
}
运行结果:
18.创建一个服务器程序
编写服务的回调函数 如同订阅一样,节点提供的每一个服务必须关联一个回调函数,服务的回调函数原型如下:
bool function_name(
package_name::service_type::Request &req),
package_name::service_type::Response &resp)
) {
...
}
节点每次接收到一个服务请求,ROS 就执行一次回调函数。参数 Request 中包含了来自于客户端的数据。回调函数的工作是给Response 对象的数据成员赋值。 Request 和 Response 数据类型与上面在客户端使用的一致,因此需要相同的头文件和相同的包依赖关系来编译。回调函数返回 true 表明成功,返回 false 则表示失败。
#include <ros/ros.h>
#include <std_srvs/Empty.h>
#include <geometry_msgs/Twist.h>
bool forward = true;
bool toggleForward (std_srvs::Empty::Request &req, std_srvs::Empty::Response &resp) {
forward = !forward;
ROS_INFO_STREAM("Now sending " <<(forward ? "forward" : "rotate") << "commands.");
return true ;
}
int main(int argc, char** argv) {
ros::init(argc, argv, "pubvel_toggle");
ros::NodeHandle nh ;
// Register our service with the master .
ros::ServiceServer server = nh.advertiseService ("toggle_forward", &toggleForward);
// Publish commands, using the latest value for forward ,
// until the node shuts down.
ros::Publisher pub = nh.advertise <geometry_msgs::Twist>("turtle1/cmd_vel", 1000);
ros::Rate rate(2);
while(ros::ok()) {
geometry_msgs::Twist msg;
msg.linear.x = forward ? 1.0 : 0.0;
msg.angular.z = forward ? 0.0 : 1.0;
pub.publish(msg);
ros::spinOnce();
rate.sleep();
}
}
在该例中, Request 和 Response 都使用了 std_srvs/Empty (空字符串)作为其数据类型,因此无需针对这两个对象做任何数据处理。回调函数的唯一工作是切换一个称为 forward 的全局布尔变量,用于管理在主函数中发布的速度消息
为了测试pubvel_toggle样例程序 , 编译它并且启动turtlesim_node和pubvel_toggle两个节点。两者运行的同时,你可以通过从命令行调用 toggle_forward 服务来在平移和转动中反复切换运动控制指令。rosservice call /toggle_forward, 反复执行rosservice call /toggle_forward得到试验结果如下
19.录制包文件 rosbag record -O filename.bag topic-names
20.rosbag record -a 记录当前发布的所有话题的消息。
21.rosbag record -j 启用包文件的压缩
22.回放包文件 rosbag play filename.bag,这里可以加参数,比如-l 代表循环播放 -r 0.5 代表以0.5倍速度播放 -s 10 代表从第10秒播放
23.检查文件包 rosbag info filename.bag
24.ROS的rosbag功能包里面也 提 供了名为record和play的可执行文件。和rosbag record 及rosbag play相比,这些程序有相同的功能,并且接受相同的命令行参数。所以可以
rosrun rosbag record -O filename.bag topic-names
rosrun rosbag play filename.bag
25.<node pkg="rosbag" name="record" type="record" args="-O filename.bag topic-names"/>
launch 文件可以这么调用
欢迎关注公众号: