【智能无线小车系列十】智能小车一体化测试

前面介绍了那么多,完成的设计思路是这样的:

     使用 树莓派 ,Arduino , 小车底盘 Arduino电机扩展板。摄像头,步进电机, USB无线网卡。

     结构如下:PC <---TCP---> 树莓派 <---Serial-->Arduino<---Serial-->步进电机

     PC为主控端,树莓派为服务端,Arduino为下位机驱动步进电机。PC做为主控端通过WIFI发送指令给树莓派(服务端),树莓派再将指令通过Serial 发给下位机Arduino控制下边的硬件。摄像头连接树莓派并将视频回传给PC端。后续可以考虑加入手机端控制,试想通过手机来控制小车,并将视频回传给手机,这感觉棒极了!不过这里的手机端尚未实现,不过技术上式完全可行的,实现与否应该就是时间的问题吧。

  

  下面开始进行测试:

  1、Arduino端:下面的代码执行的功能是:通过树莓派传输控制指令控制小车基本运动,具体操作指令如下,数字按键表示的是键盘上的按键。其中,按键8:——前进,按键2——后退,按键4——左转弯,按键6——右转弯,按键5——停止。

 将PC通过USB数据线与Arduino连接起来,编译上述代码,然后将其烧制到Arduino板上即可。烧制完成之后,断开数据线。

int pin1=8;
int pin2=9;
int speedpin1=11;
int pin3=6;
int pin4=7;
int speedpin2=10;
char sign;


void setup() {

  // put your setup code here, to run once:
  pinMode(pin1,OUTPUT);
  pinMode(pin2,OUTPUT);
  pinMode(speedpin1,OUTPUT);
  pinMode(pin3,OUTPUT);
  pinMode(pin4,OUTPUT);  
  pinMode(speedpin2,OUTPUT); 
  Serial.begin(9600);   
}


void loop() {
    // put your main code here, to run repeatedly:
    if(Serial.available()){
      sign=Serial.read();
      switch (sign){  
        case '6'://right
        {  
            analogWrite(speedpin1,200);//set the PWM speed as 100
            analogWrite(speedpin2,200);//set the PWM speed as 100
            digitalWrite(pin1,HIGH);
            digitalWrite(pin2,LOW);
            digitalWrite(pin3,HIGH);
            digitalWrite(pin4,LOW);    
            break;
        }

   
    case '2'://backward
    {
      analogWrite(speedpin1,200);//set the PWM speed as 100
      analogWrite(speedpin2,200);//set the PWM speed as 100
      digitalWrite(pin1,LOW);
      digitalWrite(pin2,HIGH);
      digitalWrite(pin3,HIGH);
      digitalWrite(pin4,LOW);    
      break;

    }

 
     case '4'://left
   {
      analogWrite(speedpin1,200);//set the PWM speed as 100
      analogWrite(speedpin2,200);//set the PWM speed as 100
      digitalWrite(pin1,LOW);
      digitalWrite(pin2,HIGH);
      digitalWrite(pin3,LOW);
      digitalWrite(pin4,HIGH);      
      break;
   }

   

     case '8'://forward
   {
      analogWrite(speedpin1,200);//set the PWM speed as 100
      analogWrite(speedpin2,200);//set the PWM speed as 100
      digitalWrite(pin1,HIGH);
      digitalWrite(pin2,LOW);
      digitalWrite(pin3,LOW);
      digitalWrite(pin4,HIGH);
      break;
   }   

     case '5'://stop
   {
     analogWrite(speedpin1,0);//set the PWM speed as 0
     analogWrite(speedpin2,0);//set the PWM speed as 0
     break;
   }   
   Serial.flush();
   }
 }


}

2、树莓派:树莓派扮演者服务器的角色。打开树莓派之后,编译并运行OLSR自组网协议。

1)配置网络为ad-hoc网络:

编辑如下的脚本程序,完成后保存为"wlan0.sh"。

#!/bin/sh
#DEV=$1
ifconfig eth0 down
ifconfig wlan0 down
iwconfig wlan0 mode ad-hoc essid 522 channel 3
ifconfig wlan0 up
ifconfig wlan0 192.168.1.52/24
echo 1 > /proc/sys/net/ipv4/conf/all/accept_source_route

这里需要注意的是,每张网卡由于每次由于所插位置的不同系统为其分配的“wlanX”名中的“X”均不相同,但是只要保持其物理位置不变,该名称也不会再发生变化。因而针对每个位置的每张网卡,在做上述修改之前需要使用命令:iwconfig 查看系统为其指定的名称以替换上述代码中的“wlan0”。不同网卡应当配置不同的ip地址,即每次都需要修改“192.168.1.52/24”中的值。

  由于不希望每次打开树莓派都要重复进行上述配置,因而希望将上述脚本添加到树莓派开机自启动程序列表中。

  不少网友们建议修改"rc.local"文件,然而 "rc.local"的执行是随机的,即不能保证每次开机都能执行,稳定性较差,故而考虑别的方法。比较稳妥的方法之一是执行脚本添加到/etc/init.d目录下。具体操作如下:

首先,切换到root权限,然后将"wlan0.sh"移动至/etc/init.d目录下。

接下来需要修改"wlan0.sh"的执行权限,执行命令:

root@raspiberrypi :/home/pi #chmod 777 /etc/init.d/wlan0.sh

然后把脚本加入到启动清单:

root@raspiberrypi :/home/pi # update-rc.d wlan0.sh defaults

最后重启系统,发现IP地址成功地开机就自动配置为我们设置好的IP地址了。

root@raspiberrypi :/home/pi # reboot

如果希望删除某个开机自启动项,可以使用如下的指令:

pi@raspberrypi $ sudo update-rc.d -f wlan0.sh remove

2)编译/运行olsrd源代码

1.首先从http://www.olsr.org/?q=download下载olsrd源码

2.解压 tar包

tar jxvf olsrd-0.6.6.tar.bz2

3.编译与安装

解压后会生成一个olsrd-0.6.6文件

#cd olsrd-0.6.6   //进入olsrd-0.6.6目录

首先,切换进入olsrd-0.6.8的文件目录,里面的文件目录结构如下所示:

通常在ubuntu下编译(make)的时候会提示错误,提示缺少flex、bison,所以在编译make之前我们需要安装flex、bison两个插件,需要联网。安装命令为:

root@raspiberrypi #olsrd-0.6.8 $ apt-get install flex  bison   //在root权限下
pi@raspiberrypi #olsrd-0.6.8 $ Sudo  apt-get install flex bison  //在普通模式下

下载并安装完成之后编译文件,

pi@raspiberrypi #olsrd-0.6.8 $make //   编译
pi@raspiberrypi #olsrd-0.6.8 $make install //  编译后会生成olsrd目标文件,安装olsrd
pi@raspiberrypi #olsrd-0.6.8 $make clean   //  清除之前编译生成的中间文件
pi@raspiberrypi #olsrd-0.6.8 $make libs //  编译库文件
pi@raspiberrypi #olsrd-0.6.8 $make install_libs //  安装库

安装成功后,修改配置文件"/etc/olsrd/oldrd.conf",添加相应的网卡接口

用vim  打开/etc/olsrd/olsrd.config

pi@raspiberrypi #olsrd-0.6.8 $ vim /etc/olsrd/olsrd.config

在配置文件的最后有 “<OLSRd-Interface1>” “<OLSRd-Interface2>” ,在其后添加 “wlanX”,其中X为你的工作无线网卡。

可以通过iwconfig  查看当前使用的无线网卡,通常为“wlan0”。

最后,运行olsrd

pi@raspiberrypi #olsrd-0.6.8 $sudo olsrd

如果出现以下的界面,说明运行成功了。

 

3)运行小车上的服务器程序

#!/usr/bin/env python
import socket
import serial
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind (('192.168.1.24',8180))
sock.listen(5)
while True:
           print "aaaaaaaaaaaa"
           connection,address=sock.accept()
           print "client ip is "
           print address
           try:
               connection.settimeout(5)
               buf=connection.recv(1)
               ser=serial.Serial('/dev/ttyACM0',9600)
               ser.write(buf)
               print "wwwwwwwwwwww"
           print buf
           except socket.timeout:
               print "timeout"
           connection.close()

上述配置完成之后,我们考虑将其全部依次添加到开机自启动项之中,这样树莓派每次加电启动之后就会自动运行我们的olsrd协议。完整的配置文件内容如下:

 

备注:其中olsrd程序所在位置“/usr/local/sbin/olsrd”是通过指令“which olsrd”查找到的。

3. PC 端:打开PC之后,编译并运行OLSR自组网协议。接下来运行下列python客户端程序“client.py”。

#!/usr/bin/env python
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sock.connect(('192.168.1.25',8180))

import time
#time.sleep(2)
buff=raw_input('enter:')
sock.send(buff)
print "aaaaaaaaaa"
sock.close()

上述为python代码均为单击测试代码,多机测试代码如下:

小车作为client端,代码client_new.py如下:

1 #!/usr/bin/env python
 2 import socket 
 3 import time
 4 
 5 #create the TCP socket
 6 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
 7 
 8 #"192.168.1.25" is the sever's IP address
 9 #"8180" is the port number of the sever 
10 sock.connect(('192.168.1.25',8180)) 
11 
12  
13 #time.sleep(2) 
14 while True:
15     #the receive thread is obstructed until it receive data from the sever ,
16     #or it won't run the next tatement
17     buff=sock.recv(1)
18     #when the link is disconnected ,the client will pirint "recv data is :" repeatedly
19     print "recv data is :"
20     print buff
21     #print "recv data is :{0}".foramt(buff)
22     #read form the serial ,/dev/ttyACM0 is the name of the equipment and 9600
23     #is the rate of bote
24     ser=serial.Serial('/dev/ttyACM0',9600)
25     ser.write(buf)
26 
27 sock.close() 

 PC作为sever端,代码server.py如下:

1 #!/usr/bin/env python
 2 from multiprocessing import Process, Value
 3 import socket
 4 import serial
 5 import time
 6 
 7 #"l" respresent an interger,"0" represents the original value
 8 num=Value('l',0)
 9 handle=Value('l',0)                       
10 value_change=Value('l',0)      
11 
12      
13 #user self-defined function
14 def hand(client,count):
15     while True:
16         if value_change.value==1 and num.value==count:
17             print "ready to send"
18             temp=handle.value
19             client.send(str(temp))
20             print "handle send success."
21             while value_change.value:
22                                 temp=0
23             time.sleep(0.7)
24     client.close()
25 
26 
27 
28 #mian function
29 if __name__ == '__main__':                        
30     sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
31     print "socket create success."
32     sock.bind (('192.168.1.12',8180))
33     sock.listen(1)
34     count=1
35 
36     while True:        
37         client, addr = sock.accept()
38         print "connect from :"
39         print addr
40         #fork a process to handle a new connecting client
41         t = Process(target = hand, args = [client,count])
42         t.start()
43         #t.join()    
44         print "process create success."
45 
46         count=count+1
47 
48         flag=raw_input("all the client connected?(y/n)")
49         if flag=="y":
50             #when all the client is connected 
51             #continue to send info to control
52             #need to change for dymacially connected and disconnected
53             while True:
54                 value_temp=raw_input("which client do you want to handle :")
55                 handle_temp=raw_input("your handle :")
56                 #get the number of the client need to contorl
57                 num.value=int(value_temp)
58                 #get the information that need to send to the client 
59                 handle.value=int(handle_temp)
60                 #set the condition that all the client need to read 
61                 value_change.value=1;
62                 #delay for 1 sescond for all the client to read from the shared memory
63                 time.sleep(1)
64                 #cancel the condition that all the client need to read 
65                 value_change.value=0; 
66     s.close()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

GeekerLou

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

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

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

打赏作者

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

抵扣说明:

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

余额充值