随着树莓派的普及以及4B版本推出,我们小组也决定由我负责树莓派相关部分,可惜网上的资源大多并不齐全,在操作中浪费了大量的时间。因此本文将详细总结笔者这些天的工作,力争形成全面的系统化的文章。本方法的所有相关资源都将放到附录部分,有需要可以自行下载。没有CSDN会员的可以私聊我,传邮箱也可以。不过可能回复不是很及时。
另外:本文由于内容过多,将采取链接形式,将所有我自己操作可行的文章链接替换长篇大论,但对于链接中不足的地方将详细讲解。本文的重点将放在目前任何博客没有给出解决方案的”软件包安装“上面。
由于本文是在本人尝试编译SLAM后第四天开始动笔的,所以之前可能有错误未能及时记录,有相关问题可以评论区讨论解决方法,欢迎大佬们的补充。
拿到树莓派时一般都会有对应的说明书,网上也有许多相关安装方法,安装部分不再赘述,后文会附带相关资源,但如果有希望后期用Respi系统来安装ROS,这里就要强调一下:本方法只支持burst版本,bullsyes等我花了许久也没有研究出对应的安装方法,主要区别在于bullsyes没有gcc-5的编译器以及在安装ROS时会产生python版本不匹配,安装对应版本又报错对应python编译器不匹配,但未找到安装方法。如果有那位大佬成功了,欢迎评论区留言。
笔者采用的是C++编程,如果想看python程序可以参考http://huishao.cc/ 的文章,他在这方面写的很详细。(由于一开始是安装bullsyes,还未测试burst系统是否足够兼容,应该是没有问题的)
更加全面的函数讲解可以参考http://wiringpi.com/ 里面有所有函数的使用方法。
对于芯片L293D,可以参考https://zhuanlan.zhihu.com/p/340063310
using namespace std;
#include
#include
#include
#include
#include
#define HW_011 0x48
#define HC_SR04_Echo 2
#define HC_SR04_Trig 3
#define SWITCH 0
#define L293D_EN 21
#define L293D_IN1 22
#define L293D_IN2 23
#define GongFang 24
#define FengMing 1
#define JQC3FFSZ 4
#define LED_R 29
#define LED_B 27
#define LED_G 28
int fd;
volatile int start;
unsigned int time0;
unsigned int time1;
// C璋冧綆闊?
int CL[] = {0, 131, 147, 165, 175, 196, 211, 248};
// C璋冧腑闊?
int CM[] = {0, 262, 294, 330, 350, 393, 441, 495};
// C璋冮珮闊?
int CH[] = {0, 525, 589, 661, 700, 786, 882, 990};
int pu[] = {CM[3],CM[3],CM[2],CM[3],CM[3],CM[5],CM[3],CM[2],CM[3],\
CM[1],CM[1],CM[2],CM[3],CM[5],CM[3],CM[2],CM[2],CM[1],CM[2],\
CM[3],CM[5],CM[3],CM[6],CM[5],CM[6],CM[5],CM[5],CM[3],CM[5],\
CM[5],CM[3],CM[2],CM[3],CM[5],CM[3],CM[2],CM[2],CM[2],CM[1],CM[2],\
CM[3],CM[3],CM[2],CM[3],CM[3],CM[5],CM[3],CM[2],CM[3],\
CM[1],CM[1],CM[2],CM[3],CM[5],CM[3],CM[2],CM[2],CM[1],CM[2],\
CM[3],CM[5],CM[3],CM[6],CM[5],CM[6],CM[5],CM[5],CM[3],CM[5],\
CM[5],CM[3],CM[2],CM[3],CM[5],CM[3],CM[2],CM[2],CM[2],CM[1],CM[1]};
int len[] = {4,2,2,8,2,2,2,2,8,4,2,2,2,2,4,4,2,2,8,6,1,1,2,6,2,2,2,2,7,1,4,2,2,4,2,2,4,2,2,8,\
4,2,2,8,2,2,2,2,8,4,2,2,2,2,4,4,2,2,8,6,1,1,2,6,2,2,2,2,7,1,4,2,2,4,2,2,4,2,2,8};
void init ()
{
if (0 > wiringPiSetup())
{
cout<<"Setup Error\r\n";
exit(-1);
}
fd = wiringPiI2CSetup(HW_011);
if (fd == -1)
{
cout<<"I2C Setup Error\r\n";
exit(-1);
}
if (softPwmCreate(L293D_EN,0,100) != 0)
{
cout<<"softPwm Setup Error\r\n";
exit(-1);
}
if (softToneCreate(GongFang) != 0)
{
cout<<"softTone Setup Error\r\n";
exit(-1);
}
pinMode(SWITCH,INPUT);
pinMode(HC_SR04_Trig,OUTPUT);
pinMode(HC_SR04_Echo,INPUT);
pinMode(L293D_IN1,OUTPUT);
pinMode(L293D_IN2,OUTPUT);
pinMode(FengMing,PWM_OUTPUT);
pinMode(JQC3FFSZ,OUTPUT);
pinMode(LED_R,OUTPUT);
pinMode(LED_G,OUTPUT);
pinMode(LED_B,OUTPUT);
}
void begin()
{
start ++;
cout<<"Switch has been touched\r\n";
delay(1000);
}
void time()
{
if (digitalRead(HC_SR04_Echo) == 1)
{
time0 = micros();
}
if (digitalRead(HC_SR04_Echo) == 0)
{
time1 = micros();
}
}
int main(void)
{
init();
cout<<"init success, push switch to start\r\n";
cout<<"It use interrupt to get information\r\n";
wiringPiISR(SWITCH, INT_EDGE_RISING, begin);
wiringPiISR(HC_SR04_Echo, INT_EDGE_BOTH, time);
while (1)
{
if (start == 0)
{
continue;
}
cout<<"First, let\'s open our LED by different color.\r\n";
cout<<"It use digitalWrite to control LED\r\n";
for (int i = 0; i <= 7; i ++)
{
digitalWrite(LED_R, (i & 1) ? HIGH : LOW);
digitalWrite(LED_G, (i & 2) ? HIGH : LOW);
digitalWrite(LED_B, (i & 4) ? HIGH : LOW);
delay(500);
}
cout<<"Then, let\'s get the infomation from HW-011\r\n";
cout<<"It use I2C wire to read or write data\r\n";
wiringPiI2CWrite(fd, 0x04); //in this way, it will check every interface one by one
wiringPiI2CRead(fd); //release the register
delay(500);
int i = 0;
while (start < 2)
{
int value = wiringPiI2CRead(fd);
switch (i & 3)
{
case 0: cout<<"0: "<<value<<"\t";
break;
case 1: cout<<"1: "<<value<<"\t";
break;
case 2: cout<<"2: "<<value<<"\t";
break;
case 3: cout<<"3: "<<value<<"\r\n";
break;
}
i++;
delay(500);
}
cout<<"After that, let\'s detect the distant from HC-SR04\r\n";
cout<<"It use interrupt and digitalWrite to control to culculate distance\r\n";
while (start < 3)
{
digitalWrite(HC_SR04_Trig, HIGH);
delay(1000);
digitalWrite(HC_SR04_Trig, LOW);
while (time1 < time0)
delay(10);
cout<<"The distance is: "<<(time1 - time0) * 340.0 / 2.0<<"\r\n";
time0 = time1 = 0;
delay(500);
}
cout<<"Now, let\'s control the motor by different speed\r\n";
cout<<"It use softPwm to control speed\r\n";
cout<<"please input the speed percentege, to stop by more than 100 or less than -100\r\n";
int speed;
while (cin>>speed)
{
if (speed > 100 || speed < -100) {
softPwmWrite(L293D_EN,0);
break;
}
else if (speed > 0) {
softPwmWrite(L293D_EN, speed);
digitalWrite(L293D_IN1, HIGH);
digitalWrite(L293D_IN2, LOW);
} else {
softPwmWrite(L293D_EN, -speed);
digitalWrite(L293D_IN1, LOW);
digitalWrite(L293D_IN2, HIGH);
}
}
cout<<"How could we do if we want to use harder Pwm?\r\n";
cout<<"Let\'s use GPIO 1 to control fengming mechine\r\n";
for (int i = 0; i <= 1024; i += 64)
{
pwmWrite(FengMing, i);
delay(500);
// pwmWrite(FengMing, 0);
// delay(500);
}
cout<<"At last, let\'s start our gongfang\r\n";
cout<<"It use JQC3FFSZ to control it open and use softTone to control it frequency\r\n";
delay(10000);
digitalWrite(JQC3FFSZ, HIGH);
cout<<"start music\r\n";
for (int i = 0; i < 80; i ++)
{
softToneWrite(GongFang,pu[i]);
delay(125 * len[i]);
softToneWrite(GongFang, 0);
delay(10);
}
delay(500);
break;
}
cout<<"Goodbye!\r\n";
return 0;
}
首先确保你的系统是burst系列,最好是10版本
参考链接:https://blog.csdn.net/jzhd2015/article/details/108218350
上面那个链接已经非常详细的讲述了如何安装ROS-Melodic,对于相关的资源也会在附录中提供。但rosdep init的部分对我已经不再适用了,我的办法是:进入/usr/lib/python2.7/dist-packages/ (这里要稍微注意一下python的版本,有的有可能是python3.7什么的,但操作思路都是一样的。依次输入命令:
cd /usr/lib/python2.7/dist-packages/
find . -type f | xargs grep “raw.githubusercontent”
这时会找出所有包含raw.githubusercontent的文件,将其中所有.py文件中的 https://raw.githubusercontent/.com/ros/rosdistro/master/ 替换成 https:/gitee.com/zhao-xuzuo/rosdistro/raw/master/ 这样就可以成功完成init和后续update的工作了。
这个链接中由于安装comm版本,所以只到roscore就结束了,但无法运行turtle节点测试,而且对于SLAM来说,comm的软件包是完全不够用的,经过本人连续一周的测试,重装系统,甚至拷贝ubuntu中的软件包都没有结果后,终于摸索出了如何安装软件包,将在下一个章节中详细讨论。
当出现诸如:
CMake Error at /opt/ros/hydro/share/genmsg/cmake/genmsg-extras.cmake:255 (message): Messages depends on unknown pkg: nav_msgs (Missing find_package(nav_msgs?)) Call Stack (most recent call first): ax2550/CMakeLists.txt:22 (generate_messages)
等错误时,如果简单的上网搜索,只会看到适用sudo apt-get install 。。。的方法,但是这个对于树莓派原生系统来说,已经不再有作用了。因为压根就没有对应的ros-melodic系列的软件包QAQ,直接拷贝是不行的,因为毕竟是.cpp代码,还需要编译的。。。。
对于大部分软件包(对于SLAM来说就是除了OpenCV、PCL、Ceres以外的软件包,这两个后面会讲),既然apt无法安装,那就可以退而求其次,适用rosinstall来安装嘛,如果有人想更加深入的理解其中的含义,可以搜索rosinstall和wstool的官网,相信更加深层次的官网讲的会比我好,这里我来教如何适用。
比如如果出现了类似下面这样的报错:
那么我们就可以在命令行中输入如下命令:
rosinstall_generator tf --rosdistro melodic --deps --tar > melodic-tf.rosinstall
wstool merge -t src melodic-tf.rosinstall
将第一个tf替换为报错中缺少的包,melodic_tf.rosintall替换为一个自己定义好的,不冲突命名的.rosinstall文件, wtool 命令替换为.rosinstall文件名。再输入:
wstool update -t src
没有报错就说明成功完成软件包的安装,再次编译会发现已经不再报这个文件找不到了。
上面那个说的是通解,但如果是需要编译SLAM的话,用下面这个集成的命令,会让编译更加快一些:
rosinstall_generator tf sensor_msgs nav_msgs image_transport geometry_msgs cv_bridge --rosdistro melodic --deps --tar > melodic_slam.rosinstall
wstool merge -t src melodic_slam.rosinstall
wstool update -t src
还有一个特殊的pcl_conversions,报错是这样的:
但是输入:
rosinstall_generator pcl_conversions --rosdistro melodic --deps --tar > melodic-pcl_conversions.rosinstall
wstool merge -t src melodic-pcl_conversions.rosinstall
wstool update -t src
但很奇怪并没有成功。。。大概是这并不是在编译时出现的问题,所以并不能靠这个方法解决吧。。。
网上也没有解决方法,只好把他们放到工作空间src,要用到pcl_conversions包(比如A-Loam-devel),include下面了。。。
没有能截图,但报错格式和上面的那个差不多。
OpenCV的编译时间很长,所以,尽量不要尝试去一个个试错。
而且目前网上没有一个是完全没有错误的。。。
cd ~/opencv-3.4.1/
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE
-D CMAKE_INSTALL_PREFIX=/usr/local
-D INSTALL_C_EXAMPLES=ON
-D INSTALL_PYTHON_EXAMPLES=ON
-D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-3.4.1/modules
-D ENABLE_PRECOMPILED_HEADERS=OFF
-D BUILD_EXAMPLES=ON …
错误截图:
这方面资源网上真的不是很多。。找到一个比较不错的网站,链接:https://blog.csdn.net/mush_room/article/details/78411846 里面大部分都是很适用的,文章后面也给出了树莓派的安装方法,但有几个小问题要声明一下。
git clone https://github.com/PointCloudLibrary/pcl.git -b pcl-1.8.1
用来切换到对应的分支上。
2. cmake那里会报两个错误,一个是
– The imported target “vtk” references the file
“/usr/bin/vtk”
but this file does not exist. Possible reasons include:
- The file was deleted, renamed, or moved to another location.
- An install or uninstall procedure did not complete successfully.
- The installation package was faulty and contained
“/usr/lib/cmake/vtk-6.2/VTKTargets.cmake”
but not all the files it references
这里参考文章https://www.icode9.com/content-4-1055883.html
输入
sudo ln -s /usr/bin/vtk6 /usr/bin/vtk
还有一个是
No package ‘metslib’ found
这里参考https://blog.csdn.net/yunluoxiaobin/article/details/103078386就可以成功啦。
最后一个估计不是谁都会碰到,就是
Could NOT find Boost (missing: iostreams) (found suitable version “1.58.0”, minimum required is “1.40.0”) Call Stack (most recent call first):
如果遇到了,重新按照https://blog.csdn.net/jzhd2015/article/details/108218350编译安装一下boos_1.58.0就好了。
出现这样的标志就代表cmake完成了。
参考链接http://ceres-solver.org/installation.html
没什么好多说的,按着来就行,没有的附录有资源。make install时别忘了sudo。
但是!!!
再最后会出现冲突,参考博客https://blog.csdn.net/qq_41586768/article/details/107541917
所以大家可以试着去弄这个博客的东西。。。亲测可行,不需要最后 6.编译ceres_curve_fiiting也是可以的。
在整整折腾了近一周后,几乎每天满载负荷,终于出现了这个
终于在不懈的努力下,我完成了编译!!!!!!!!!!!!!!!!!!!
真的是太不容易了,文章中的每一个报错几乎都折腾了许久,每一个一笔带过的地方都折腾了十几分钟到几天不等。。。。。。而且很多编译都是两三个小时以上QAQ
然而这一切并不算完成,运行时依旧会出现问题,比如rviz,gzbol等等的安装。本人会在后续继续补充这些内容。感谢各位的关注。怕什么真理无穷,进一寸有一寸欢喜!!!
附录:
1.树莓派对应burst系统:https://download.csdn.net/download/weixin_46238869/85171752
5. 树莓派烧录软件:https://download.csdn.net/download/weixin_46238869/85171768
6. 树莓派连接软件putty:https://download.csdn.net/download/weixin_46238869/85171821
7. s树莓派连接软件vnc:https://download.csdn.net/download/weixin_46238869/85171786
8. 硬件演示视频:https://download.csdn.net/download/weixin_46238869/85171846
9. OpenCV缺失包,boost.zip:https://download.csdn.net/download/weixin_46238869/85171796
10. ceres-solver软件包:https://download.csdn.net/download/weixin_46238869/85179317