rosserial_arduino软件包对于用户是为了work out-of-box ,但用户可能需要更改ros.h和ArduinoHardware.h以更好地适应他们的需要。在本教程中,我们将更改两个文件以演示一些高级设置。
1 条件
1.1 硬件
-
-
FTDI分线板或类似的UART到USB转换器
- 两个设备的USB电缆
- 一些跳线连接两个设备
1.2 目标
1.2 发布者/订阅者数量和输入/输出缓冲区
Arduino Mega有8 kB的SRAM,远远超过大多数其他Arduino板(Uno有2 kB,Leonardo有2.5 kB)。这使我们能够拥有更多的发布者/订阅者并使用更大的消息。虽然我们可能永远不需要为Arduino Mega change those numbers,因为默认值足够大,但对于SRAM有限的小型主板,我们需要减少内存使用量。为了演示如何操作,我们将发布者/订阅者的数量从25/25减少到10/15,输入/输出缓冲区大小减少512/512字节到128/256字节。
1.2.2 更改串行端口
Arduino Mega总共有4个串口:
对象名称 |
RX Pin |
TX Pin |
Serial |
0 |
1 |
SERIAL1 |
19 |
18 |
Serial2 |
17 |
16 |
Serial3 |
15 |
14 |
通常,我们使用Serial与Arduino Mega进行通信,Serial连接到UART到USB桥接器,并显示为我们在计算机上看到的端口。但是对于本教程,我们将使用Serial1。由于Serial1无法直接与计算机通信,因此我们使用UART转USB桥(FTDI分线板)。
1.2.3 改变Baudate
默认情况下,rosserial使用57600作为通信的波特率。这个速率不是Arduino可以达到的最大速率,当有大量信息需要发送回ROS时,波特率可能成为瓶颈。
工作在16 Mhz的Arduino Mega可以通过高达每秒2M位(bps)的波特率进行通信,其他板(如Teensy 3.2)可以达到4.6 Mbps。Arduino串行库的低效率很快成为高波特率的瓶颈,我们无法真正受益于增加的波特率。(更多相关信息点击这里)
在本教程中,我们将波特率从57.6 Kbps更改为500 Kbps。
2 程序
我们将为此示例提供3个源文件。main sketch,ros.h和ArduinoHardware.h。因为我们的许多变化都在幕后并且不影响我们如何使用rosserial,所以使用hello world sketch能够进行最少的修改。原始的ros.h和ArduinoHardware.h可以在rosocrial_arduino包的src / ros_lib /中找到,也可以在Arduino库中生成的ros_lib中找到。您可以直接修改它们以达到相同的效果,但建议将它们添加到sketch文件夹中,以便每个sketch进行更改并持续重新生成ros_lib。
2.1 Main Sketch
我们将首先创建一个新草图并将以下代码复制到它:
/*
* rosserial Publisher Example
* Prints "hello world!"
*/
#include "ros.h"
#include <std_msgs/String.h>
ros::NodeHandle nh;
std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg);
char hello[13] = "hello world!";
void setup()
{
nh.initNode();
nh.advertise(chatter);
}
void loop()
{
str_msg.data = hello;
chatter.publish( &str_msg );
nh.spinOnce();
delay(1000);
}
2.2 ros.h
ros.h是对NodeHandle定义,我们将通过单击Serial Monitor下面的向下箭头图标在Arduino中创建一个新选项卡,将其命名为ros.h,并将以下内容复制到它:
#ifndef _ROS_H_
#define _ROS_H_
#include "ros/node_handle.h"
#include "ArduinoHardware.h"
namespace ros
{
// default is 25, 25, 512, 512
typedef NodeHandle_<ArduinoHardware, 10, 15, 128, 256> NodeHandle;
// This is legal too and will use the default 25, 25, 512, 512
//typedef NodeHandle_<ArduinoHardware> NodeHandle;
}
#endif
2.3 ArduinoHardware.h
ArduinoHardware.h,是Arduino平台的硬件定义,与ros.h类似,我们将创建一个名为ArduinoHardware.h的新选项卡,并将以下代码复制到其中:
#ifndef ROS_ARDUINO_HARDWARE_H_
#define ROS_ARDUINO_HARDWARE_H_
#if ARDUINO>=100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#include <HardwareSerial.h>
#define SERIAL_CLASS HardwareSerial
class ArduinoHardware
{
public:
ArduinoHardware()
{
iostream = &Serial1;
baud_ = 500000;
}
void setBaud(long baud)
{
this->baud_= baud;
}
int getBaud()
{
return baud_;
}
void init()
{
iostream->begin(baud_);
}
int read()
{
return iostream->read();
};
void write(uint8_t* data, int length)
{
for(int i=0; i<length; i++)
{
iostream->write(data[i]);
}
}
unsigned long time()
{
return millis();
}
protected:
SERIAL_CLASS* iostream;
long baud_;
};
#endif
3 程序解释
3.1 Main Sketch
#include "ros.h"
#include <std_msgs/String.h>
我们发现它的主草图唯一的区别是如何包括ros.h,括号<ros.h>在原来的Hello World是由引号替换“ros.h”。这告诉编译器在本地路径中查找文件,然后在其他库中搜索它。其他一切都与你好世界的例子相同。
3.2 ros.h
// default is 25, 25, 512, 512
typedef NodeHandle_<ArduinoHardware, 10, 15, 128, 256> NodeHandle;
这使我们的NodeHandle有10个Publishers,15个Subscriber,128个字节用于输入缓冲区,256个字节用于输出缓冲区。
3.3 ArduinoHardware.h
#include <HardwareSerial.h>
#define SERIAL_CLASS HardwareSerial
这里我们包括与之通信的串行对象的标头。串行对象类必须拥有read(),write()和begin(baudrate)成员函数等实现。Serial和Serial1都是HardwareSerial对象。
ArduinoHardware()
{
iostream = &Serial1;
baud_ = 500000;
}
在这里,我们为ArduinoHardware创建默认构造函数,并将我们使用的串口设置为Serial1,并将波特率设置为500 kbps。
4 编译并上传代码
代码是像往常一样编译和上传的。 编译后,您将能够看到这样的代码消息
Sketch uses 9,552 bytes (3%) of program storage space. Maximum is 253,952 bytes.
Global variables use 1,130 bytes (13%) of dynamic memory, leaving 7,062 bytes for local variables. Maximum is 8,192 bytes.
通过改变缓冲区大小和发布者/订阅者数量,动态内存使用量也将发生变化。
5 运行代码
我们现在将使用Serial1与ROS进行通信。断开USB电缆与Arduino的连接,将FTDI分线板连接到Arduino Mega,如下所示:
FTDI Arduino Mega
VCC -> 5V
TXO -> Pin 19
RXI -> Pin 18
GND -> GND
使用USB电缆将FTDI分线板连接到计算机。
现在,在新的终端窗口中启动roscore:
roscore
接下来,运行rosserial客户端应用程序,将Arduino消息转发给ROS的其余部分。确保使用正确的串口:
rosrun rosserial_python serial_node.py _port:=/dev/ttyUSB0 _baud:=500000
最后,通过启动新的终端窗口并输入以下内容,观看来自Arduino的问候:
rostopic echo chatter
6 附加功能
ros.h和ArduinoHardware.h许可证。
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2011, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote prducts derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/