(三)ROS工具

常用命令

//查看话题列表
rostopic list
//查看某个话题信息
rostopic info 话题名
//输出某个话题的内容
rostopic echo 话题名
//查看节点列表
rosnode list
//节点拓扑结构
rqt_graph

自动启动多个节点

创建launch启动文件
在这里插入图片描述
编写launch启动文件

<launch>
<node name="minimal_subscriber" pkg="my_minimal_nodes" type="my_minimal_subscriber"/>
<node name="minimal_publisher" pkg="my_minimal_nodes" type="my_minimal_publisher"/>
</launch>

注:
通过指定三个值来启动一个节点,第一个值是节点名node name,第二个值是程序包名pkg,第三个值是可执行文件名type。在这里node name可以随便写,也就是给了你一次重新命名的机会。
运行launch启动文件
在这里插入图片描述
注:
在使用launch启动文件的时候,不需要启动可执行节点roscore
查看运行结果
在这里插入图片描述

在ROS控制台观察输出

rqt_console

在这里插入图片描述

使用rosbag记录并回放数据

当系统运行时,我们可以指定记录一系列话题,rosbag会订阅这些话题并将发布的消息以及时间戳记录在包文件中,生成的文件会保存在运行命令的同一目录下。

rosbag record 话题名

在这里插入图片描述
rosbag回放包文件,重建已记录的系统环境。

rosbag play 包名.bag

在这里插入图片描述

rqt_plot

这里我们就以一个仿真器和控制器交互为例子,来展示一下怎么使用rqt_plot可视化吧。

//仿真器
#include <ros/ros.h>
#include <std_msgs/Float64.h>
std_msgs::Float64 g_velocity;
std_msgs::Float64 g_force;
void myCallback(const std_msgs::Float64& message_holder)
{
	g_force.data=message_holder.data;
	ROS_INFO("received force value is: %f",message_holder.data);
}
int main(int argc,char **argv)
{
	ros::init(argc,argv,"minimal_simulator");
	ros::NodeHandle n;
	ros::Subscriber my_subscriber_object=n.subscribe("force_cmd",1,myCallback);
	ros::Publisher my_publisher_object=n.advertise<std_msgs::Float64>("velocity",1);
	double mass=1.0; //质量为1kg
	double dt=0.01; //10毫秒采一次样
	double sample_rate=1.0/dt;
	g_velocity.data=0.0;
	g_force.data=0.0;
	ros::Rate naptime(sample_rate);
	while(ros::ok())
	{
		g_velocity.data=g_velocity.data+(g_force.data/mass)*dt;
		my_publisher_object.publish(g_velocity);
		ROS_INFO("velocity = %f",g_velocity.data);
		ros::spinOnce();
		naptime.sleep();
	}
	return 0;
}
//控制器
#include <ros/ros.h>
#include <std_msgs/Float64.h>
std_msgs::Float64 g_velocity;
std_msgs::Float64 g_vel_cmd;
std_msgs::Float64 g_force;
void myCallbackVelocity(const std_msgs::Float64& message_holder)
{
	g_velocity.data=message_holder.data;
	ROS_INFO("received velocity value is: %f",message_holder.data);
}
void myCallbackVelCmd(const std_msgs::Float64& message_holder)
{
	g_vel_cmd.data=message_holder.data;
	ROS_INFO("received velocity command value is: %f",message_holder.data);
}
int main(int argc,char **argv)
{
	ros::init(argc,argv,"minimal_controller");
	ros::NodeHandle n;
	ros::Subscriber my_subscriber_object1=n.subscribe("velocity",1,myCallbackVelocity);
	ros::Subscriber my_subscriber_object2=n.subscribe("vel_cmd",1,myCallbackVelCmd);
	ros::Publisher my_publisher_object=n.advertise<std_msgs::Float64>("force_cmd",1);
	g_velocity.data=0.0;
	g_vel_cmd.data=0.0;
	g_force.data=0.0;
	double Kv=1.0;
	double dt_controller=0.1;
	double sample_rate=1.0/dt_controller;
	double vel_err=0.0;
	ros::Rate naptime(sample_rate);
	while(ros::ok())
	{
		vel_err=g_vel_cmd.data-g_velocity.data;
		g_force.data=Kv*vel_err;
		my_publisher_object.publish(g_force);
		ROS_INFO("force command = %f",g_force.data);
		ros::spinOnce();
		naptime.sleep();
	}
	return 0;
}

上面的代码是什么意思呢?这里首先有三个话题“vel_cmd”,“force_cmd”,“velocity”,这三个话题分别代表了期望速度、实际力、实际速度。没错,到这里大家应该已经能猜到了,就是一个简单的F=ma。
仿真器根据v=v0+at计算实际速度,并发布实际速度,同时订阅实际力并显示。
控制器根据F=ma计算实际力,并发布实际力,同时订阅实际速度、期望速度并显示。
那么在操作的时候,首先要打开roscore,然后再运行控制器节点和仿真器节点(这两个顺序就无所谓了),然后需要手动发布一个期望速度的话题消息,这样控制器才可以订阅,最后执行rqt_plot命令就可以看到变化曲线了。
在这里插入图片描述
原谅我没有截到rqt_plot的图,这个速度实在是太快了,但是我确实是成功了的,可以看下面两张图的实际速度velocity在“慢慢”的逼近期望速度(实际上是很快就逼近了,导致我还没有打开rqt_plot它就结束了)。
在这里插入图片描述
在这里插入图片描述
算了,最后再贴一张图吧,不然大家都不知道plot长啥样的,在官网上找的图,和这个例子没有关系…
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值