-
Ubuntu 14.04 (Trusty armhf)
-
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu trusty main" > /etc/apt/sources.list.d/ros-latest.list'
-
Set up your keys
-
sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net --recv-key 0xB01FA116
Installation
First, make sure your Debian package index is up-to-date:
-
sudo apt-get update
There are many different libraries and tools in ROS - not all compile fully on ARM. You can also install ROS packages individually.
-
ROS-Base: (Bare Bones) ROS package, build, and communication libraries. No GUI tools.
-
sudo apt-get install ros-indigo-ros-base
-
Add Individual Packages
- You can install a specific ROS package (replace underscores with dashes of the package name):
-
sudo apt-get install ros-indigo-PACKAGE
- e.g.
sudo apt-get install ros-indigo-navigation
-
To find available packages, use:
apt-cache search ros-indigo
确保Raspbian OS已经更新
[html] view plaincopy
1. sudo apt-get update
2. sudo apt-get upgrade
2.2 安装 bootstrap 依赖
[html] view plaincopy
1. sudo apt-get install python-setuptools
2. sudo easy_install pip
3. sudo pip install -U rosdep rosinstall_generator wstool rosinstall
2.3 初始化 rosdep
[html] view plaincopy
1. sudo rosdep init
2. rosdep update
3. 编译ROS
3.1创建workspace来编译ROS
[html] view plaincopy
1. mkdir ~/ros_catkin_ws
2. cd ~/ros_catkin_ws
接下来下载ROS代码,ROS提供了两个代码包
1)ROS-Comm:这是官方推荐的,但只包含基本的ROS通讯功能,没有navigation, TF, action, RViz等 GUI工具
2) Desktop: 完整的ROS功能,适合所有机器人应用。我们选择安装这个。
下面的命令下载并生产编译package列表,会很花时间
[html] view plaincopy
1. rosinstall_generator desktop --rosdistro indigo --deps --wet-only --exclude roslisp --tar > indigo-desktop-wet.rosinstall
2. wstool init -j8 src indigo-desktop-wet.rosinstall
如果中途下载中断,下面的命令会接着下载:
[html] view plaincopy
1. wstool update -j 4 -t src
3.2 解决依赖
libconsole-bridge-dev, liburdfdom-headers-dev, liburdfdom-dev, liblz4-dev,和 collada-dom-dev 这五个包并不在Raspbian里面,需要手工编译下载
创建新目录下载这5个包
[html] view plaincopy
1. <span style="font-size:18px;">mkdir ~/ros_catkin_ws/external_src
2. sudo apt-get install checkinstall cmake</span>
安装libconsole-bridge-dev:
[html] view plaincopy
1. <span style="font-size:18px;">cd ~/ros_catkin_ws/external_src
2. sudo apt-get install libboost-system-dev libboost-thread-dev
3. git clone https://github.com/ros/console_bridge.git
4. cd console_bridge
5. cmake .
6. sudo checkinstall make install</span>
当checkinstall询问是否改变安装选项时,选择[2],将名字从"console-bridge"改为 "libconsole-bridge-dev"
接下来的两个问题连续选择'n',否则会编译出错
安装liblz4-dev
[html] view plaincopy
1. <span style="font-size:18px;">$ cd ~/ros_catkin_ws/external_src
2. $ wget http://archive.raspbian.org/raspbian/pool/main/l/lz4/liblz4-1_0.0~r122-2_armhf.deb
3. $ wget http://archive.raspbian.org/raspbian/pool/main/l/lz4/liblz4-dev_0.0~r122-2_armhf.deb
4. $ sudo dpkg -i liblz4-1_0.0~r122-2_armhf.deb liblz4-dev_0.0~r122-2_armhf.deb</span>
安装liburdfdom-headers-dev
[html] view plaincopy
1. <span style="font-size:18px;">$ cd ~/ros_catkin_ws/external_src
2. $ git clone https://github.com/ros/urdfdom_headers.git
3. $ cd urdfdom_headers
4. $ cmake .
5. $ sudo checkinstall make install</span>
当checkinstall询问是否改变安装选项时,选择[2],将名字从"urdfdom-headers"改为 "liburdfdom-headers-dev"
接下来的两个问题连续选择'n',否则会编译出错
安装liburdfdom-dev
[html] view plaincopy
1. <span style="font-size:18px;">$ cd ~/ros_catkin_ws/external_src
2. $ sudo apt-get install libboost-test-dev libtinyxml-dev
3. $ git clone https://github.com/ros/urdfdom.git
4. $ cd urdfdom
5. $ cmake .
6. $ sudo checkinstall make install</span>
当checkinstall询问是否改变安装选项时,选择[2],将名字从"urdfdom"改为 "liburdfdom-dev"
接下来的两个问题连续选择'n',否则会编译出错
安装collada-dom-dev
[html] view plaincopy
1. <span style="font-size:18px;">$ cd ~/ros_catkin_ws/external_src
2. $ sudo apt-get install libboost-filesystem-dev libxml2-dev
3. $ wget http://downloads.sourceforge.net/project/collada-dom/Collada%20DOM/Collada%20DOM%202.4/collada-dom-2.4.0.tgz
4. $ tar -xzf collada-dom-2.4.0.tgz (如果普通用户解压有问题,则用root用户进行解压)
5. $ cd collada-dom-2.4.0
6. $ cmake .
7. $ sudo checkinstall make install</span>
当checkinstall询问是否改变安装选项时,选择[2],将名字从"collada-dom"改为 "collada-dom-dev"
接下来的两个问题连续选择'n',否则会编译出错
3.3 通过rosdep解决依赖
[html] view plaincopy
1. <span style="font-size:18px;">$ cd ~/ros_catkin_ws
2. $ rosdep install --from-paths src --ignore-src --rosdistro indigo -y -r --os=debian:wheezy</span>
上面命令会便利所有的package并递归安装依赖
3.4 开始编译ROS
$ sudo./src/catkin/bin/catkin_make_isolated --install -DCMAKE_BUILD_TYPE=Release--install-space /opt/ros/indigo
常见错误:
编译过程中会编译180多个package并同时安装在/opt/ros/indigo目录,经常会报出'collada_parser' ,'collada_urdf' ,'rviz','visualization_tutorials','rqt_robot_plugins/rqt_rviz'这几个包出错而中断安装。解决办法就是将这些个包从目录 ~/ros_catkin_ws/src 目录中移出,再重新编译整个ROS.最后单独建立一个workspace,将些包放到src目录中。再执行下面命令:
sudo./src/catkin/bin/catkin_make_isolated --install -DCMAKE_BUILD_TYPE=Release--install-space /opt/ros/indigo
如果仍然报错,则需要重新一个一个安装步骤3.2中的五个包,每安装一个重新编译一遍,成功编译的包可以删除,直到最后都编译成功。
如果还是报错,就根据报错的详细信息,将某些导致编译报错的源代码文件排除编译列表(一般是修改包目录下的CMakesfiles.txt文件,将导致编译报错的源代码文件注释掉)。
树莓派学习笔记——UART使用
树莓派——UART使用点击打开链接
本文将详细介绍树莓派的串口(UART)配置和使用,并结合一个modbus RTU从机的例子说明树莓派串口的应用。
在开始前说明以下几点
【1】树莓派UART端口的位置
TXD位于HEAD-8
RXD位于HEAD-10
GND位于HEAD-6(可选其他GND)
【2】树莓派的TXD应接USB转串口设备的RXD,当然如果测试失败请交换RXD和TXD的顺序
【3】经过很多次的测试(N>25),当波特率为115200时打开树莓派的UART时,树莓派会莫名其妙的发送一字节0xF8,该问题始终无法解决。不过波特率为9600时并没有此问题,猜测是树莓派硬件或内核驱动问题。
【4】树莓派的串口默认为SSH调试使用,若要使用串口需要修改两处文件。
图1 树莓派 UART位置
1.修改两处文件
【1】/boot/cmdline.txt
【输入以下指令】
sudo nano /boot/cmdline.txt
【删除红色部分】
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
【最终变为】
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
【2】/etc/inittab
【输入以下指令】
sudo nano /etc/inittab
【注释最后一行内容】
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
2.使用minicom
配置完之后便可测试一下树莓派的UART是否正常工作,而minicom便是一个简单好用的工具。minicom是linux平台串口调试工具,相当于windows上的串口调试助手。
【1】minicom安装
sudo apt-get install minicom
【2】minicom启动
minicom -b 9600 -o -D /dev/ttyAMA0
-b代表波特率,-D代表端口,/dev/ttyAMA0 类似于windows中的COM1,-o功能暂时未知。
图2 minicon界面
【3】minicom发送内容
直接在控制台中输入内容即可,如果minicom打开了回显可在控制台中观察到输出内容,如果回显关闭则控制台中没人任何反应,千万不要以为minicom没有正常工作。
【4】minicom回显控制
先Ctrl+A,再E。可翻转回显状态(原来回显打开则此事回显关闭)
【5】minicom回显关闭
先Ctrl+A,再Q。
3.使用pyserial
minicom仅满足调试用途,如果需要编程解决问题那么python的serial扩展库——pyserial则是一个不错的选择。pyserial模块非常好用,后面的文章还会分析如何使用pyserial控制GPRS模块。
【pyserial安装】
安装pyserial扩展库有很多种方法,可使用pip或者easy_install安装,也可以直接选择apt-get工具安装。
若使用apt-get工具安装,可输入以下指令
sudo apt-get install python-serial
【串口回显程序】
非常简单的一个串口程序,树莓派通过串口返回接收的内容。
- # -*- coding: utf-8 -*
- import serial
- import time
- # 打开串口
- ser = serial.Serial("/dev/ttyAMA0", 9600)
- def main():
- while True:
- # 获得接收缓冲区字符
- count = ser.inWaiting()
- if count != 0:
- # 读取内容并回显
- recv = ser.read(count)
- ser.write(recv)
- # 清空接收缓冲区
- ser.flushInput()
- # 必要的软件延时
- time.sleep(0.1)
-
- if __name__ == '__main__':
- try:
- main()
- except KeyboardInterrupt:
- if ser != None:
- ser.close()
# -*- coding: utf-8 -*
import serial
import time
# 打开串口
ser = serial.Serial("/dev/ttyAMA0", 9600)
def main():
while True:
# 获得接收缓冲区字符
count = ser.inWaiting()
if count != 0:
# 读取内容并回显
recv = ser.read(count)
ser.write(recv)
# 清空接收缓冲区
ser.flushInput()
# 必要的软件延时
time.sleep(0.1)
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
if ser != None:
ser.close()
4.总结
由于可借助python标准库使得树莓派的串口格外好用。是不是可以拿树莓派做一个Modbus RTU从机,的确可以请期待后面的博文吧。
5.参考资料
【1】minicom使用 国外博客
【2】elinux python-serial 安装pyserial及例程等
- # -*- coding: utf-8 -*
- import serial
- import time
- # 打开串口
- ser = serial.Serial("/dev/ttyAMA0", 9600)
- def main():
- while True:
- # 获得接收缓冲区字符
- count = ser.inWaiting()
- if count != 0:
- # 读取内容并回显
- recv = ser.read(count)
- ser.write(recv)
- # 清空接收缓冲区
- ser.flushInput()
- # 必要的软件延时
- time.sleep(0.1)
- if __name__ == '__main__':
- try:
- main()
- except KeyboardInterrupt:
- if ser != None:
- ser.close()
# -*- coding: utf-8 -*
import serial
import time
# 打开串口
ser = serial.Serial("/dev/ttyAMA0", 9600)
def main():
while True:
# 获得接收缓冲区字符
count = ser.inWaiting()
if count != 0:
# 读取内容并回显
recv = ser.read(count)
ser.write(recv)
# 清空接收缓冲区
ser.flushInput()
# 必要的软件延时
time.sleep(0.1)
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
if ser != None:
ser.close()
串口操作需要的头文件
#include <stdio.h> /*标准输入输出定义*/ #include <stdlib.h> /*标准函数库定义*/ #include <unistd.h> /*Unix 标准函数定义*/ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> /*文件控制定义*/ #include <termios.h> /*PPSIX 终端控制定义*/ #include <errno.h> /*错误号定义*/ |
|
在 Linux 下串口文件是位于 /dev 下的
串口一 为 /dev/ttyS0
串口二 为 /dev/ttyS1
打开串口是通过使用标准的文件打开函数操作:
int fd; /*以读写方式打开串口*/ fd = open( "/dev/ttyS0", O_RDWR); if (-1 == fd){ /* 不能打开串口一*/ perror(" 提示错误!"); } |
|
最基本的设置串口包括波特率设置,效验位和停止位设置。
串口的设置主要是设置 struct termios 结构体的各成员值。
struct termio { unsigned short c_iflag; /* 输入模式标志 */ unsigned short c_oflag; /* 输出模式标志 */ unsigned short c_cflag; /* 控制模式标志*/ unsigned short c_lflag; /* local mode flags */ unsigned char c_line; /* line discipline */ unsigned char c_cc[NCC]; /* control characters */ }; |
设置这个结构体很复杂,我这里就只说说常见的一些设置:
波特率设置
下面是修改波特率的代码:
struct termios Opt; tcgetattr(fd, &Opt); cfsetispeed(&Opt,B19200); /*设置为19200Bps*/ cfsetospeed(&Opt,B19200); tcsetattr(fd,TCANOW,&Opt); |
设置波特率的例子函数:
/** *@brief 设置串口通信速率 *@param fd 类型 int 打开串口的文件句柄 *@param speed 类型 int 串口速度 *@return void */ int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300, }; <!-- code sample is too wide -->int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, }; void set_speed(int fd, int speed){ int i; int status; struct termios Opt; tcgetattr(fd, &Opt); for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) { if (speed == name_arr[i]) { tcflush(fd, TCIOFLUSH); cfsetispeed(&Opt, speed_arr[i]); cfsetospeed(&Opt, speed_arr[i]); status = tcsetattr(fd1, TCSANOW, &Opt); if (status != 0) { perror("tcsetattr fd1"); return; } tcflush(fd,TCIOFLUSH); } } } |
效验位和停止位的设置:
无效验 | 8位 | Option.c_cflag &= ~PARENB; Option.c_cflag &= ~CSTOPB; Option.c_cflag &= ~CSIZE; Option.c_cflag |= ~CS8; |
奇效验(Odd) | 7位 | Option.c_cflag |= ~PARENB; Option.c_cflag &= ~PARODD; Option.c_cflag &= ~CSTOPB; Option.c_cflag &= ~CSIZE; Option.c_cflag |= ~CS7; |
偶效验(Even) | 7位 | Option.c_cflag &= ~PARENB; Option.c_cflag |= ~PARODD; Option.c_cflag &= ~CSTOPB; Option.c_cflag &= ~CSIZE; Option.c_cflag |= ~CS7; |
Space效验 | 7位 | Option.c_cflag &= ~PARENB; Option.c_cflag &= ~CSTOPB; Option.c_cflag &= &~CSIZE; Option.c_cflag |= CS8; |
设置效验的函数:
/** *@brief 设置串口数据位,停止位和效验位 *@param fd 类型 int 打开的串口文件句柄 *@param databits 类型 int 数据位 取值 为 7 或者8 *@param stopbits 类型 int 停止位 取值为 1 或者2 *@param parity 类型 int 效验类型 取值为N,E,O,,S */ int set_Parity(int fd,int databits,int stopbits,int parity) { struct termios options; if ( tcgetattr( fd,&options) != 0) { perror("SetupSerial 1"); return(FALSE); } options.c_cflag &= ~CSIZE; switch (databits) /*设置数据位数*/ { case 7: options.c_cflag |= CS7; break; case 8: options.c_cflag |= CS8; break; default: fprintf(stderr,"Unsupported data size/n"); return (FALSE); } switch (parity) { case 'n': case 'N': options.c_cflag &= ~PARENB; /* Clear parity enable */ options.c_iflag &= ~INPCK; /* Enable parity checking */ break; case 'o': case 'O': options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/ options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'e': case 'E': options.c_cflag |= PARENB; /* Enable parity */ options.c_cflag &= ~PARODD; /* 转换为偶效验*/ options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'S': case 's': /*as no parity*/ options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB;break; default: fprintf(stderr,"Unsupported parity/n"); return (FALSE); } /* 设置停止位*/ switch (stopbits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: fprintf(stderr,"Unsupported stop bits/n"); return (FALSE); } /* Set input parity option */ if (parity != 'n') options.c_iflag |= INPCK; tcflush(fd,TCIFLUSH); options.c_cc[VTIME] = 150; /* 设置超时15 seconds*/ options.c_cc[VMIN] = 0; /* Update the options and do it NOW */ if (tcsetattr(fd,TCSANOW,&options) != 0) { perror("SetupSerial 3"); return (FALSE); } return (TRUE); } |
需要注意的是:
如果不是开发终端之类的,只是串口传输数据,而不需要串口来处理,那么使用原始模式(Raw Mode)方式来通讯,设置方式如下:
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/ options.c_oflag &= ~OPOST; /*Output*/ |