四足两轮小车二合一遥控机器人(第二版完工,可下代码)

2014-01-2110.5万
精华项目
AI 快速预览详细 收起
该项目介绍了如何制作一款四足两轮小车二合一遥控机器人。第一版使用上网本作为主机,但存在视频和控制延时的问题。第二版改用了刷了openwrt的路由器,解决了这些问题,并提供了完整的C++和opencv代码。通过这些改进,用户可以实现局域网遥控和视频流传输。
第一个版本,用了上网本做机器人主机,通过其它终端遥控。实现其它确实很简单,还能独立完成一些复杂任务。但是遥控的角度上还是有些很多弊端,比如视频和控制都有明显延时,psp容易,上网本耗电过多,如果选择从机器人的电池获得供电,一次充满玩不了多久就没电了。基于上述情况,决定把遥控改了。
喜欢该贴的、下载代码的顺手点个支持吧

第一版:
材料清单:
2020铝型材若干
32路舵机控制板一块
Arduino uno控制板一块
上网本一台
11个180度舵机
2个360度舵机(当直流电机用)
舵机支架若干
usb摄像头一个配红外镜头
4个红外led灯
12V锂电池一块同时为上网本和控制板供电

搭好的机器人:
四足两轮小车二合一遥控机器人(第二版完工,可下代码)图1四足两轮小车二合一遥控机器人(第二版完工,可下代码)图2
四足两轮小车二合一遥控机器人(第二版完工,可下代码)图3
四足两轮小车二合一遥控机器人(第二版完工,可下代码)图4
四足两轮小车二合一遥控机器人(第二版完工,可下代码)图5
四足两轮小车二合一遥控机器人(第二版完工,可下代码)图6
四足两轮小车二合一遥控机器人(第二版完工,可下代码)图7
四足两轮小车二合一遥控机器人(第二版完工,可下代码)图8
四足两轮小车二合一遥控机器人(第二版完工,可下代码)图9
四足两轮小车二合一遥控机器人(第二版完工,可下代码)图10


模式切换的测试视频:


wifi遥控(带视频传输)是可以用可烧写的无线路由器实现的,例如TP Link703N,也可以在网上买已经烧写好openwrt的。
手上没有这类路由器,偷个懒就用5年前的上网本来实现好了。上网本和uno利用串口通信,上网本上的程序用c语言编写。可轻松实现键盘事件。这样偷懒有个好处,可以利用移动设备直接对上网本遥控,从而控制机器人,比如使用windowsphone上的应用pcremote。也可以利用其他计算机对机器人实现远程遥控。简单的桌面托管(例如qq)就可以了,当然也可以自己编写。另外还可以用c语言和opencv实现视频识别等,让机器人独立完成一些任务。

手上有台闲置已久的psp。这里就是用psp disp来完成遥控,带视频流。

关于C语言的按键反应和串口通信,简单做下介绍。
这里以clr项目为例,示例代码如下,非常简单
  1. #include "stdafx.h"
  2. #include "windows.h"
  3. using namespace System;
  4. using namespace System::IO::Ports;
  5. int main(array<System::String ^> ^args)
  6. {
  7. Console::WriteLine(L"Serial test");
  8. SerialPort^ arduino;
  9. arduino = gcnew SerialPort("COM3",9600);
  10. arduino->Open();
  11. int i=1;
  12. while(1){
  13. if(i%2==1)
  14. arduino->WriteLine("H");
  15. else
  16. arduino->WriteLine("L");
  17. Sleep(1000); //延时1秒,其头文件为window.h
  18. i=i+1;
  19. }
  20. return 0;
  21. }
  22. 前面提到过opencv。为了以后的任务,如视频识别等,决定直接使用opencv。对于这里的遥控任务而言,可以直接打开usb摄像头,而且自带了键盘事件函数。示例代码如下
  23. #include "stdafx.h"
  24. #include <opencv2/opencv.hpp> // opencv库函数
  25. using namespace System;
  26. using namespace System::IO::Ports;
  27. using namespace cv;
  28. int main(array<System::String ^> ^args)
  29. {
  30. Console::WriteLine(L"Serial test");
  31. cvNamedWindow( "window1", CV_WINDOW_AUTOSIZE);
  32. SerialPort^ arduino;
  33. arduino = gcnew SerialPort("COM3",9600);
  34. arduino->Open();
  35. int i=1;
  36. while(1)
  37. {
  38. char c = waitKey(1000); //延时1秒,等待键盘事件,返回键值
  39. switch(c)
  40. {
  41. case 'h':
  42. arduino->WriteLine("H");
  43. break;
  44. case 'l':
  45. arduino->WriteLine("L");
  46. }
  47. }
  48. cvDestroyWindow("window1"); // 销毁窗口
  49. return 0;
  50. }
复制代码


要使用opencv的函数,需要对项目做一些配置,可以参考中国官网上的安装教程。另外需要注意的是
waitKey()函数只有在打开了一个cv窗口的情况下有效。所以在主函数里第二行添加了语句:
               cvNamedWindow( "window1", CV_WINDOW_AUTOSIZE); //创建一个cv窗口
再放几张界面的图片和截屏
四足两轮小车二合一遥控机器人(第二版完工,可下代码)图11

四足两轮小车二合一遥控机器人(第二版完工,可下代码)图13

四足两轮小车二合一遥控机器人(第二版完工,可下代码)图12

两个四足模式的视频





局域网遥控


完整的c语言程序代码可以在附件下载



第二版:
还是继续要视频传输,和wifi遥控。这次用一个刷了openwrt的路由代替上网本,今后图像处理等任务可以交由上位机完成。因为不需要负载上网本,对机器人的结构做了些改动。

四足两轮小车二合一遥控机器人(第二版完工,可下代码)图15

我选择了一个mini无线路由器。拆开壳改装的时候才发现主板和tp link 703n是一样的。然后就是把板子上的tp_in和tp_out接出两根线用于和arduino串口通信。供电不用miniusb口,还要跳出两根电源线,电源线负极也是串口通信的共地线。为了扩大点wifi信号范围,放弃了原有的wifi贴片天线,连接了一个外接天线。
四足两轮小车二合一遥控机器人(第二版完工,可下代码)图16

硬件全部改造完成了,然后就是漫长的刷机过程。不多说了,网上资料教程多的是。嫌麻烦也可以从网上直接买个烧写好的路由器。连上摄像头和arduino就可以测试了。目前测试用的是网上的上位机软件(计算机和手机)。这些软件支持按键自定义,还不错,下位机部分就可以完全保持不变了。pc端上位机软件,过于花哨了,有的功能不需要的也放在上面。android端自定义功能不算太全面。
四足两轮小车二合一遥控机器人(第二版完工,可下代码)图14

四足两轮小车二合一遥控机器人(第二版完工,可下代码)图17

着手自己编写程序。等程序完成后再跟大家分享。最后还是要回归到psp控制,psp程序现在也只能自己编写了。程序的编写难点有两个,一个视频传输,另一个是数据的传输。


C++和opencv方案
前面说了,之后图像处理的任务会交给上位机。第一版中,控制端的计算机就是用的C++搭opencv的方案。所以继续沿用该方案设计pc端程序。建立一个C++ console项目,添加相关opencv库的添加和路劲配置,可以参考网上的资料。
如果按照网上的资料进行路由器烧写,那么视频流的地址为
http://192.168.1.1:8080/?action=stream
路由器成功烧写openwrt的话,可以用firefox浏览器在改地址下成功打开摄像头。opencv里的VideoCapture是可以利用ip地址打开网络摄像头的
如果直接使用视频流的地址是打不开的,因为VideoCapture的参数需要一个文件拓展名,所以在使用的时候给它加上一个虚拟变量。烧写了openwrt的路由器传输的视频流是mjpg。我们新的视频流地址就是
http://192.168.1.1:8080/?action=stream&type=.mjpg
现在来看这部分的完整代码,轻松打开摄像头。
  1. #include "stdafx.h"
  2. #include "opencv2/opencv.hpp"
  3. #include "highgui.h"
  4. #include "iostream"
  5. using namespace System;
  6. using namespace cv;
  7. using namespace std;
  8. int main(array<System::String ^> ^args)
  9. {
  10.     Console::WriteLine(L"Hello World");
  11.         
  12.         cvNamedWindow( "camera", CV_WINDOW_AUTOSIZE);
  13.         cvMoveWindow("camera",0,0);
  14.         
  15.         const string cameraAddress = "http://192.168.1.1:8080/?action=stream&type=.mjpg"; //带虚拟参数的视频流ip地址
  16.         VideoCapture vcap;
  17.         Mat frame;
  18.         if(! vcap.open(cameraAddress))
  19.         {
  20.                 Console::WriteLine(L"ERROR");
  21.                 return -1;
  22.         }
  23.         while(1)
  24.         {
  25.                 char c = cvWaitKey(10);
  26.                 vcap.read(frame);
  27.                 imshow("camera",frame);
  28.                 if(c==27)
  29.                         break;
  30.         }
  31.         cvDestroyWindow("camera");
  32.     return 0;
  33. }
复制代码


控制部分。
按照网上的资料给路由器烧写openwrt后,控制地址为  http:\\192.168.1.1
端口号为:2001路由默认的通信波特率为9600
控制的实现使用C/C++的Network编程。首先需要添加头文件 System.dll
然后添加下面的命名空间
  1. using namespace System;
  2. using namespace Sytem::Net;
  3. using namespace Sytem::Net::Sockets;
复制代码

定义一个IPAddress类对象来解析控制地址。
  1. System::String^ controlip = "192.168.1.1";   // 不能包含 http:\\
复制代码

定义一个IPEndPoint类对象,建立控制地址的端点。
  1. System::String^ port = "2001";
复制代码

最后定义一个Socket类对象,用Socket类的函数完成建立连接,数据发送和接收。
  1. Socket^ c = gcnew Socket(ipe->AddressFamily,SocketType::Stream,ProtocolType::Tcp);
复制代码

其中scode和rcode的类型是字节数组,scode是要发送的数据,rcode用于保存要接收的数据
  1. array<Byte>^ scode = Encoding::UTF8->GetBytes("arduino");  //arduino是要发送的数据,转换为Byte数组,保存到scod
复制代码

用下面的Arduino代码来测试路由器的串口控制。
  1. int led = 13;
  2. void setup(){
  3.   pinMode(led,OUTPUT);
  4.   Serial.begin(9600);
  5. }
  6. void loop(){
  7.   char c;
  8.   
  9.   if(Serial.available())
  10.   c = Serial.read();
  11.   
  12.   if(c == 49)
  13.   digitalWrite(led,HIGH);
  14.   else
  15.   digitalWrite(le,LOW);
  16. }
复制代码
下面是包含摄像头打开和发送测试数据的代码。
  1. #include "stdafx.h"
  2. #include "opencv2/opencv.hpp"
  3. #include "highgui.h"
  4. #include "iostream"
  5. #using <System.dll>
  6. using namespace System;
  7. using namespace System::Net;
  8. using namespace System::Net::Sockets;
  9. using namespace System::Text;
  10. using namespace cv;
  11. using namespace std;
  12. int main(array<System::String ^> ^args)
  13. {
  14.     Console::WriteLine(L"Hello World");
  15.         
  16.         cvNamedWindow( "camera", CV_WINDOW_AUTOSIZE);
  17.         cvMoveWindow("camera",0,0);
  18.         
  19.         const string cameraAddress = "http://192.168.1.1:8080/?action=stream&type=.mjpg";
  20.         System::String^ controlip = "192.168.1.1";
  21.         System::String^ port = "2001";
  22.         VideoCapture vcap;
  23.         Mat frame;
  24.         if(! vcap.open(cameraAddress))
  25.         {
  26.                 Console::WriteLine(L"ERROR");
  27.                 return -1;
  28.         }
  29.         IPAddress^ ips = IPAddress::Parse(controlip);
  30.         IPEndPoint^ ipe = gcnew IPEndPoint(ips,Convert::ToInt32(port));
  31.         Socket^ c= gcnew Socket(ipe->AddressFamily,SocketType::Stream,ProtocolType::Tcp);
  32.         c->Connect(ipe);
  33.         array<Byte>^ scode = Encoding::UTF8->GetBytes("1");
  34.         array<Byte>^ rcode = gcnew array<Byte>(256);
  35.         while(c->Connected)
  36.         {
  37.                 scode = Encoding::UTF8->GetBytes("0");
  38.                 c->Send(scode,scode->Length,SocketFlags::None);
  39.                 //c->Receive(rcode,c->Available,SocketFlags::None);
  40.                 char k = cvWaitKey(10);
  41.                 vcap.read(frame);
  42.                 imshow("camera",frame);
  43.                 scode = Encoding::UTF8->GetBytes("1");
  44.                 c->Send(scode,scode->Length,SocketFlags::None);
  45.                 if(k==27)
  46.                         break;
  47.         }
  48.         cvDestroyWindow("camera");
  49.         c->Close();
  50.     return 0;
  51. }
复制代码
最后可以看到Arduino控制板上的led等L在闪烁。现在来控制机器人。Arduino的代码完全不需要改动。把第一版的c++代码移植到上面的代码里就完成了。完整的代码可以从下面附件下。C++程序运行截图
四足两轮小车二合一遥控机器人(第二版完工,可下代码)图19



安卓控制端的代码也完成了。相比之下,代码简单得多,就不多解释了。大家可以直接下载源码。稍微说明下,如果以我的安卓代码继续做的话,注意我用了自定义的SurfaceView类,其次Manifest文件里要添加以下代码,这是网络通信协议
  1. <uses-permission android:name="android.permission.INTERNET" >
  2.     </uses-permission>
  3.     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
  4.     </uses-permission>
  5.     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" >
  6.     </uses-permission>
复制代码
安卓控制界面照片
四足两轮小车二合一遥控机器人(第二版完工,可下代码)图18


用安卓平板遥控的视频。PC端的遥控视频就不发了


下一阶段就是PSP的控制了,正在酝酿中。完成后再跟大家分享。可能还会编写windowsphone版本的。

喜欢该贴的、下载代码的顺手点个支持吧







创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(42)
JOVI
JOVI
学习学习
三春牛-创客
三春牛-创客
赞赞赞赞赞!好棒!
三春牛-创客
三春牛-创客
厉害厉害
花生编程
花生编程
泰裤辣!!!不错不错!
花生编程
花生编程
赞赞赞赞赞!!!
花生编程
花生编程
厉害厉害
Amos Young
Amos Young
楼主自己做的吗? 好牛B的玩法。。
Amos Young
Amos Young
好创意,可以多做一些扩展应用
腿毛利小五郎
腿毛利小五郎
帅啊支持!
耘想
耘想
66666666666666666
耘想
耘想
评论内容
绝罅
绝罅
6666666666
bobbi
bobbi
厉害厉害
qq376911787
qq376911787
大佬
碧海
碧海
感觉带视觉的作品都好高端啊
红通通
红通通
可以啊,太会玩了
EmSECpn6
EmSECpn6
牛B玩法,玩出新高度
DFSkangKjBr
DFSkangKjBr

学习学习,谢谢分享。
DFSkangKjBr
DFSkangKjBr
学习中,希望自己能成功做出一个来!谢谢分享!
霍仰一个后仰
霍仰一个后仰
厉害