Arduino学习笔记(16)-- ROS master和Arduino node通信

目录

1. 环境配置

2. 测试例子程序

2.1 hello world发布者节点

2.2 订阅者节点

2.3 自定义消息类型Point.msg

3. 小结


1. 环境配置

简要概括上一篇文章https://blog.csdn.net/hhaowang/article/details/104659483中讲述的ROS+Arduino的环境配置和使用方法。

  • 安装rosserial软件包
sudo apt-get install ros-kinetic-rosserial-arduino
sudo apt-get install ros-kinetic-rosserial
  • 编译catkin_ws项目,source ~/.bashrc
  • 安装ros_lib库,其中<sketchbook>是arduino的开发环境路径,也可以在~/Arduino路径下打开终端执行删除和安装库操作
  cd <sketchbook>/libraries
  rm -rf ros_lib
  rosrun rosserial_arduino make_libraries.py .
  • 重启arduino IDE,可以看到ros_lib的例子。官网上有rosserial_arduino教材,可以结合例子学习。
  • 以Arduino为下位机,创建Publisher节点,在ROS上位机运行roscore并连接串口,就可以与Arduino通讯。
roscore
rosrun rosserial_python serial_node.py 

串口信息和节点信息就可以显示出来,Arduino与ROS上位机连接成功。


2. 测试例子程序

2.1 hello world发布者节点

Arduino程序:

/*
 * rosserial Publisher Example
 * Prints "hello world!"
 */

#include <ros.h>            //包含ros头文件
#include <std_msgs/String.h>  //标准消息类型String.h

//声明节点句柄nh
ros::NodeHandle  nh;  

//声明std_msgs类型对象str_msg
std_msgs::String str_msg;
//在Arduino层声明一个Publisher,发布话题为chatter,消息为str_msg引用
ros::Publisher pub_str("chatter", &str_msg);

char hello[30] = "hello world! I am a publisher from Arduino!";

void setup()
{
  nh.initNode(); //初始化Pub节点
  nh.advertise(pub_str); //声明chatter话题
}

void loop()
{
  str_msg.data = hello;
  pub_str.publish( &str_msg );
  nh.spinOnce();
  delay(1000);
}

终端命令:

roscore
rosrun rosserial_python serial_node.py

新终端查看节点和话题详情:

rostopic list
rostopic echo chatter
rosnode list


2.2 订阅者节点

Arduino节点代码:

/* 
 * rosserial Subscriber Example
 * Blinks an LED on callback
 */

#include <ros.h>
#include <std_msgs/Empty.h>

ros::NodeHandle  nh;

void messageCb( const std_msgs::Empty& toggle_msg){
  digitalWrite(13, HIGH-digitalRead(13));   // blink the led
}
//订阅者节点
ros::Subscriber<std_msgs::Empty> sub("toggle_led", &messageCb );

void setup()
{ 
  pinMode(13, OUTPUT);
  nh.initNode();
  nh.subscribe(sub);
}

void loop()
{  
  nh.spinOnce();
  delay(1);
}

ROS上位机:

rosrun rosserial_python serial_node.py

节点信息:端口/dev/ttyUSB0 波特率 57600

rqt

使用rqt向话题发布消息,观察arduino

分别以10hz和20hz的频率刷新Arduino LED灯闪烁频率。


2.3 自定义消息类型Point.msg

在ros_lib中已经有了Point.msg的自定义消息,使用Arduino发布消息至point_info话题。

生成的Point.h文件

#ifndef _ROS_msgs_demo_Point_h

#define _ROS_msgs_demo_Point_h



#include <stdint.h>

#include <string.h>

#include <stdlib.h>

#include "ros/msg.h"



namespace msgs_demo

{



  class Point : public ros::Msg

  {

    public:

      typedef float _x_type;

      _x_type x;

      typedef float _y_type;

      _y_type y;

      typedef float _z_type;

      _z_type z;



    Point():

      x(0),

      y(0),

      z(0)

    {

    }



    virtual int serialize(unsigned char *outbuffer) const

    {

      int offset = 0;

      offset += serializeAvrFloat64(outbuffer + offset, this->x);

      offset += serializeAvrFloat64(outbuffer + offset, this->y);

      offset += serializeAvrFloat64(outbuffer + offset, this->z);

      return offset;

    }



    virtual int deserialize(unsigned char *inbuffer)

    {

      int offset = 0;

      offset += deserializeAvrFloat64(inbuffer + offset, &(this->x));

      offset += deserializeAvrFloat64(inbuffer + offset, &(this->y));

      offset += deserializeAvrFloat64(inbuffer + offset, &(this->z));

     return offset;

    }



    const char * getType(){ return "msgs_demo/Point"; };

    const char * getMD5(){ return "4a842b65f413084dc2b10fb484ea7f17"; };



  };



}

#endif

Arduino程序:

#include <ros.h>
#include "msgs_demo/Point.h"

//声明句柄
ros::NodeHandle nh;
msgs_demo::Point point; //声明自定义消息类型对象point(x,y,z)-float64

//创建消息发布者,话题名
ros::Publisher pub("point_info", &point);

void setup() {
  // put your setup code here, to run once:
  //初始化节点信息和发布者
  nh.initNode();
  nh.advertise(pub);
  point.x = 1.0;
  point.y = 1.0;
  point.z = 1.0;
}

void loop() {
  // put your main code here, to run repeatedly:

  if(Serial.available()){
    point.x += 0.1;
    point.y += 0.2;
    point.z += 0.3;
  }
  
  pub.publish(&point);
  nh.spinOnce();
  delay(1000);

}

ROS上位机:

查看消息内容:

rqt_graph:

 

3. 小结

实现Arduino与ROS通信需要配置各自的开发环境,在ROS端安装串口驱动,并编译catkin_ws项目,生成相应的Arduino库文件;在Arduino端包含响应的消息头文件,声明并定义通信类型topic、action、service,并声明节点信息,如发布传感器信息的发布者、订阅底盘速度的订阅者节点等,烧录之后,在ROS端打开串口驱动,便可以实现ROS与arduino的通信。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Techblog of HaoWANG

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值