ROS技巧系列 - ROS与Arduino进行高效稳定的串口通信(两种通信方式对比)

ROS与Arduino通信方式分类

ROS与Arduino通信方式大致分为两种:
 1)基于ros的通信机制,如话题,服务,行为等方式,这个时候需要用到rosserial库,需要安装rosserial_arduino。这种方式的好处是不需要知道串口之间的通信协议,直接发布和订阅来传递参数,缺点是不稳定,偶尔出现订阅不上话题,或者arduino设备连接不上的问题。不推荐。
 2)直接利用串口通信的规则,即设置好串口的所有配置参数,然后打开串口,通过write()和read()函数进行写和读。但是必须提前获知串口的通信协议,如“M01 30” 表示第一个关节,转30度。该方法上下位机间通信稳定性高。推荐。

1.基于ros通信机制

基于ROS以主题为主要通信媒介的特征,Arduino需要作为一个节点,用订阅话题的形式接收上位机规划出的理想位置或速度,用发布话题的形式,将电机或传感器的数据发布出去,以此方式将Arduino加入到整个控制系统中。而在之间起到桥梁作用的则是rosserial功能包,该功能包是ROS中专为Arduino通信设计的。建立通信方式的步骤如下:
  1)首先需要在ubuntu系统中安装Arduino IDE,安装指令为:sudo apt-get install arduino,完成后会生成arduino的文件目录。
  2)安装rosserial功能包,安装完成后,会生成rosserial_arduino文件夹,安装指令为:sudo apt-get install ros-indigo-rosserial-arduino;
  3)将rosserial_arduino文件夹下的ros_lib文件复制到Arduino库目录sketchbook/libraries。
上述步骤完成之后,再次打开Arduino IDE,在examples中就会看到ros_lib项。如图所示,这样在编写程序时,添加ros.h头文件后,就可以调用ros类中的成员函数和变量了。
在这里插入图片描述
  4)在arduino中编写节点即可,与普通创建ros节点方法相同。
  5)编写完arduino中节点后,直接启动rosserial_python中的serial_node.py即可,注意串口号,如:
  $ rosrun rosserial_python serial_node.py /dev/ttyACM0

2.基于串口通信方式

在这里忽略任何ros属性,直接按照正常的串口通信来实现,下面这个代码展示了在ros节点(即订阅话题又发布话题)中如何使用串口通信,其关键代码如下:

try
	{
		_serial.setPort("/dev/ttyACM0"); # 指定串口号,可利用udev方式锁定设备号,避免断电或插拔后串口号变换
		_serial.setBaudrate(115200); # 波特率
		serial::Timeout to = serial::Timeout::simpleTimeout(1000);
		_serial.setTimeout(to);
		_serial.open();
		ROS_INFO_STREAM("Port has been open successfully");
	}

全部代码如下,可直接拷贝使用,话题回调函数根据自己需要进行修改,但必须提前获知通信协议。

#include <ros/ros.h>
#include <serial/serial.h>
#include <std_msgs/String.h>
#include <std_msgs/Int8.h>
#include <std_msgs/Bool.h>
#include <std_msgs/Empty.h>
#include <geometry_msgs/Twist.h>
#include <swiftpro/position.h>
#include <iostream>
using namespace std;
serial::Serial _serial;				
swiftpro::SwiftproState pos;

void position_write_callback(const swiftpro::position& msg)
{
	std::string Gcode = "";
	std_msgs::String result;
	char x[10];
	char y[10];
	char z[10];
	pos.x = msg.x;
	pos.y = msg.y;
	pos.z = msg.z;
	sprintf(x, "%.2f", msg.x);
	sprintf(y, "%.2f", msg.y);
	sprintf(z, "%.2f", msg.z);
	Gcode = (std::string)"G0 X" + x + " Y" + y + " Z" + z + " F5" + "\r\n";
	ROS_INFO("%s", Gcode.c_str());
	_serial.write(Gcode.c_str());
	result.data = _serial.read(_serial.available());
}

int main(int argc, char** argv)
{	
	ros::init(argc, argv, "swiftpro_control_node");
	ros::NodeHandle nh;
	swiftpro::SwiftproState swiftpro_state;
	ros::Subscriber sub1 = nh.subscribe("position_topic", 1, position_write_callback);
	ros::Publisher 	 pub1 = nh.advertise<std_msgs::Bool>("whether_ready", 1);
	ros::Rate loop_rate(20);
	try
	{
		_serial.setPort("/dev/ttyACM0");
		_serial.setBaudrate(115200);
		serial::Timeout to = serial::Timeout::simpleTimeout(1000);
		_serial.setTimeout(to);
		_serial.open();
		ROS_INFO_STREAM("Port has been open successfully");
	}
	catch (serial::IOException& e)
	{
		ROS_ERROR_STREAM("Unable to open port");
		return -1;
	}
		if (_serial.isOpen())
	{
		ROS_INFO_STREAM("Attach and wait for commands");
	}
	while (ros::ok())
	{
		pub.publish(pos);
		ros::spinOnce();
		loop_rate.sleep();
	}
		return 0;
}

  • 15
    点赞
  • 110
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
ROSArduino之间进行串口通信可以使用以下步骤: 1.在Arduino上安装ROS串口通信库,例如rosserial库。 2.编写Arduino代码,将其上传到Arduino板上,该代码应该包含ros.h头文件和串口初始化函数。 3.在ROS上创建一个节点,使用rosserial库与Arduino进行通信。 4.在ROS节点中使用发布者和订阅者来发送和接收数据。 下面是一个简单的例子,演示如何在ROS中使用rosserial库与Arduino进行通信: 1.安装rosserial库 在Arduino IDE中,选择"Sketch -> Include Library -> Manage Libraries",然后搜索"rosserial"并安装。 2.编写Arduino代码 以下是一个简单的示例代码,该代码将读取来自ROS的整数,并将其写入到串口: ``` #include <ros.h> #include <std_msgs/Int32.h> ros::NodeHandle nh; void messageReceived(const std_msgs::Int32& msg) { int value = msg.data; Serial.println(value); } ros::Subscriber<std_msgs::Int32> sub("topic_name", messageReceived); void setup() { nh.initNode(); nh.subscribe(sub); Serial.begin(9600); } void loop() { nh.spinOnce(); } ``` 3.创建ROS节点 在终端中,输入以下命令来创建ROS节点: ``` rosrun rosserial_python serial_node.py /dev/ttyUSB0 ``` 其中,/dev/ttyUSB0应该是Arduino连接到计算机上的串口设备名称。 4.使用ROS发布者和订阅者 在ROS节点中,使用以下代码来发布数据: ``` ros::NodeHandle nh; ros::Publisher pub = nh.advertise<std_msgs::Int32>("topic_name", 10); std_msgs::Int32 msg; msg.data = 42; pub.publish(msg); ``` 使用以下代码来订阅数据: ``` ros::NodeHandle nh; ros::Subscriber<std_msgs::Int32> sub = nh.subscribe("topic_name", 10, messageReceived); void messageReceived(const std_msgs::Int32& msg) { int value = msg.data; ROS_INFO("Received value: %d", value); } ``` 注意:在使用rosserial库进行通信时,需要确保Arduino板上的程序正常运行,并且串口设备名称正确。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值