基于EVK1105开发平台设计的交互式机器人小车
一. 正文(1)、项目摘要
交互式机器人小车是可以通过wifi实现数据的采集,视频监控等功能的智能控制平台。它集娱乐、现场勘测等于一体,采用了具有超强的音频解码和流媒体处理能力的AT32UC3A0512作为核心,在EVK1105开发平台上成功嵌入网页。并且实现无需插件或asp、php等语言,仅依靠html语言的交互式控制。交互式机器人小车还可以完成视频的动态监控,无需任何插件即可在网页查看相关媒体。小车的控制也是直接在网页上完成,无需任何软件。如手机上有wifi,经测试也可直接登录控制。而且在小车上增加相关传感器模块,还可直接把数据发到网页上,再结合浏览器插件便可将数据直接导入相关数据库或上传到internet。
(2)、硬件原理
2.1 系统结构图
2.2、小车驱动模块
为了加强小车的野外数据采集能力,我们将小车设计为四驱结构并且全部采用360度舵机控制。这样虽然会降低小车的运行速度,但却让小车获得较大力矩和载重能力,使其在崎岖不平的草地上一样可以行动自如。在整个交互式机器人小车结构设计上我们一共采用了6个舵机:DS04-NFC 和 FUTABA3010。
DS04-NFC是360°舵机,主要用来驱动小车前进。它的控制信号是50HZ方波信号,一个高电平脉冲持续的时间对应一个速度。高电平为1毫秒~1.5毫秒时,舵机正转(1毫秒时正转速度最快,越接近1.5毫秒越慢,1.5毫秒时舵机停转),高电平为1.5毫秒~2毫秒时舵机反转(1.5毫秒时舵机停转,越接近2毫秒反转的速度越快,2毫秒时以最快的速度反转),转弯用差速控制。FUTABA3010则拥有摄像头云台,是180°舵机,根据所给PWM占空比不同可控制摄像头的左右转和上下转。
2.3 、Arduino控制板
在本次设计中我们采用了arduino328驱动电机,它主要是以Atmel的Atmega328作为核心,将MCU内部所有资源都编为开源的函数,可直接调用、查看、修改。具体原理图如下:
2.4、 DC-DC升压模块
这一模块主要是用于为无线路由器提供电源,具体电路如下:
图(4):DC—DC升压电路
(3)、软件架构
软件部分我们主要分为三块:无线路由加motion摄像头监控、EVK1105上的Websever、Arduino上的舵机驱动。
3.1 无线路由模块
在无线路由上我们嵌入了openwrt操作系统用于管理网络连接、自动拨号、wifi控制等。UVC摄像头我们也是挂在路由器上的,采用了motion做视频管理。具体编辑如下:
root@OpenWrt:~# opkg install motion
Installing motion (3.2.11.1-1) to root...
Downloading http://downloads.x-wrt.org/xwrt/backfire/10.03/brcm63xx/packages/motion_3.2.11.1-1_brcm63xx.ipk.
Installing libjpeg (6b-1) to root...
Downloading http://downloads.x-wrt.org/xwrt/backfire/10.03/brcm63xx/packages/libjpeg_6b-1_brcm63xx.ipk.
Configuring libjpeg.
Configuring motion.
root@OpenWrt:~# vi /overlay/etc/motion.conf
# Rename this distribution example file to motion.conf
#
# This config file was generated by motion "3.2.11.1"
############################################################
# Daemon
############################################################
# Start in daemon (background) mode and release terminal (default: off)
daemon off (on->off)
# File to store the process ID, also called pid file. (default: not defined)
process_id_file /var/run/motion/motion.pid
############################################################
# Basic Setup Mode
############################################################
# Start in Setup-Mode, daemon disabled. (default: off)
setup_mode off
###########################################################
# Capture device options
############################################################
# Videodevice to be used for capturing (default /dev/video0)
# for FreeBSD default is /dev/bktr0
videodevice /dev/video0
# Image width (pixels). Valid range: Camera dependent, default: 352
width 320 (视频宽)
# Image height (pixels). Valid range: Camera dependent, default: 288
height 240 (视频高)
# Motion Detection Settings:
############################################################
# Threshold for number of changed pixels in an image that
# triggers motion detection (default: 1500)
threshold 1500 (灵敏度调节)
# Automatically tune the threshold down if possible (default: off)
threshold_tune off
# Noise threshold for the motion detection (default: 32)
noise_level 32
# Automatically tune the noise threshold (default: on)
noise_tune on
# Live Webcam Server
############################################################
# The mini-http server listens to this port for requests (default: 0 = disabled)
webcam_port 8081 #远程端口
# Quality of the jpeg images produced (default: 50)
webcam_quality 50
# Output frames at 1 fps when no motion is detected and increase to the
# rate given by webcam_maxrate when motion is detected (default: off)
webcam_motion off
# Maximum framerate for webcam streams (default: 1)
webcam_maxrate 1
# Restrict webcam connections to localhost only (default: on)
webcam_localhost off
# Limits the number of images per connection (default: 0 = unlimited)
# Number can be defined by multiplying actual webcam rate by desired number of seconds
# Actual webcam rate is the smallest of the numbers framerate and webcam_maxrate
webcam_limit 0
target_dir /tmp/cam1 保存目录
############################################################
# HTTP Based Control
############################################################
# TCP/IP port for the http server to listen on (default: 0 = disabled)
control_port 8080
# Restrict control connections to localhost only (default: on)
control_localhost on
# Output for http server, select off to choose raw text plain (default: on)
control_html_output on
# Authentication for the http based control. Syntax username:password
# Default: not defined (Disabled)
; control_authentication username:password
##############################################################
# Thread config files - One for each camera.
# Except if only one camera - You only need this config file.
# If you have more than one camera you MUST define one thread
# config file for each camera in addition to this config file.
##############################################################
# Remember: If you have more than one camera you must have one
# thread file for each camera. E.g. 2 cameras requires 3 files:
# This motion.conf file AND thread1.conf and thread2.conf.
# Only put the options that are unique to each camera in the
# thread config files.
thread /etc/thread1.conf
thread /etc/thread2.conf
# thread /etc/thread3.conf
# thread /etc/thread4.conf
3.2 EVK1105模块
这一模块中我们主要是基于Lwip在Atmel公司的EVK1105开发平台上构建一个websever,完成人与车间的互动和数据的采集。具体界面如下:
下面是关于web的一段代码:
#if (HTTP_USED == 1)
/* Standard includes. */
#include <stdio.h>
#include <string.h>
#include "conf_eth.h"
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "partest.h"
#include "serial.h"
/* Demo includes. */
/* Demo app includes. */
#include "portmacro.h"
/* lwIP includes. */
#include "lwip/api.h"
#include "lwip/tcpip.h"
#include "lwip/memp.h"
#include "lwip/stats.h"
#include "netif/loopif.h"
/* ethernet includes */
#include "ethernet.h"
#include "gpio.h"
#define GPIO_PIN_EXAMPLE_10 //传输控制代码
#define GPIO_PIN_EXAMPLE_21
#define GPIO_PIN_EXAMPLE_329
#define GPIO_PIN_EXAMPLE_430
//#include "usart.h"
/*! The size of the buffer in which the dynamic WEB page is created. */
#define webMAX_PAGE_SIZE 3072
/*! Standard GET response. */
#define webHTTP_OK "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"
/*! The port on which we listen. */
#define webHTTP_PORT ( 80 )
/*! Delay on close error. */
#define webSHORT_DELAY ( 10 )
/*! Format of the dynamic page that is returned on each connection. */
/*!网页上按钮是用表单来构建的,不同的按钮发送不同的表单数值 */
#define webHTML_START \
"<html>\
<head>\
</head>\
<BODY onLoad=\"window.setTimeout("location.href='index.html'",1000)\" bgcolor=\"#FFFFFF\" text=\"#2477E6\">\
\r\n<center><p><h1>2011 AVR Campus Design Competition</h1></p>\
<center><p>Jiangnan University</p>\
<center><p>Interactive robot control platform car</p>\
<form name=\"input\" method=\"get\" action=\"1\">\
<input name=\"f\" type=\"text\"value=\"1\" style=\"display:none\" />\
<input type=\"submit\" name=\"X_0\" id=\"X_0\" value=\"Advance\" >\
</form>\
<form name=\"input\" method=\"get\" action=\"12\">\
<input name=\"f\" type=\"text\"value=\"2\" style=\"display:none\" />\
<input type=\"submit\" name=\"X_1\" id=\"X_1\" value=\"Left \" >\
</form>\
<form name=\"input\" method=\"get\" action=\"123\">\
<input name=\"f\" type=\"text\" value=\"3\" style=\"display:none\" />\
<input type=\"submit\" name=\"X_2\" id=\"X_2\" value=\" Right \" >\
</form>\
<form name=\"input\" method=\"get\" action=\"1234\">\
<input name=\"f\" type=\"text\" value=\"4\" style=\"display:none\" />\
<input type=\"submit\" name=\"X_3\" id=\"X_3\" value=\"Retreat\" >\
</form>\
\r\n<p><form name=\"input\" method=\"get\" action=\"12345\">\
\r\n<input name=\"f\" type=\"text\" value=\"4\" style=\"display:none\" />\
\r\n<input type=\"submit\" name=\"X_4\" id=\"X_4\" value=\"add_s\" >\
\r\n</form>\
\r\n <form name=\"input\" method=\"get\" action=\"123456\">\
\r\n<input name=\"f\" type=\"text\" value=\"4\" style=\"display:none\" />\
\r\n<input type=\"submit\" name=\"X_5\" id=\"X_5\" value=\" back_s\" >\
\r\n</form></p>\
<p><form name=\"input\" method=\"get\" action=\"1234567\">\
\r\n<input name=\"f\" type=\"text\" value=\"4\" style=\"display:none\" />\
\r\n<input type=\"submit\" name=\"X_6\" id=\"X_6\" value=\"f_audio\" >\
\r\n </form>\
\r\n <form name=\"input\" method=\"get\" action=\"12345678\">\
\r\n<input name=\"f\" type=\"text\" value=\"4\" style=\"display:none\" />\
\r\n<input type=\"submit\" name=\"X_7\" id=\"X_7\" value=\"l_audio\" >\
\r\n </form>\
\r\n <form name=\"input\" method=\"get\" action=\"123456789\">\
\r\n<input name=\"f\" type=\"text\" value=\"4\" style=\"display:none\" />\
\r\n<input type=\"submit\" name=\"X_8\" id=\"X_8\" value=\"r_audio\" >\
\r\n </form>\
\r\n <form name=\"input\" method=\"get\" action=\"1234567890\">\
\r\n<input name=\"f\" type=\"text\" value=\"4\" style=\"display:none\" />\
\r\n<input type=\"submit\" name=\"X_9\" id=\"X_9\" value=\"b_audio\" >\
\r\n </form></p>"
#define webHTML_END \
"\r\n</pre>\
\r\n</font></BODY>\
</html>"
portCHAR cDynamicPage[ webMAX_PAGE_SIZE ];
portCHAR cPageHits[ 11 ];
int f;
/*! Function to process the current connection */
static void prvweb_ParseHTMLRequest( struct netconn *pxNetCon );
/*! \brief WEB server main task
* check for incoming connection and process it
*
*\param pvParameters Input. Not Used.
*
*/
portTASK_FUNCTION( vBasicWEBServer, pvParameters )
{
struct netconn *pxHTTPListener, *pxNewConnection;
/* Create a new tcp connection handle */
pxHTTPListener = netconn_new( NETCONN_TCP );
netconn_bind(pxHTTPListener, NULL, webHTTP_PORT );
netconn_listen( pxHTTPListener );
/* Loop forever */
for( ;; )
{
/* Wait for a first connection. */
pxNewConnection = netconn_accept(pxHTTPListener);
vParTestSetLED(webCONN_LED, pdTRUE);
if(pxNewConnection != NULL)
{
prvweb_ParseHTMLRequest(pxNewConnection);
}/* end if new connection */
vParTestSetLED(webCONN_LED, pdFALSE);
} /* end infinite loop */
}
/*! \brief parse the incoming request
* parse the HTML request and send file
*
*\param pxNetCon Input. The netconn to use to send and receive data.
*
*/
static void prvweb_ParseHTMLRequest( struct netconn *pxNetCon )
{
struct netbuf *pxRxBuffer;
portCHAR *pcRxString;
unsigned portSHORT usLength;
static unsigned portLONG ulPageHits;
/* We expect to immediately get data. */
pxRxBuffer = netconn_recv( pxNetCon );
if( pxRxBuffer != NULL )
{
/* Where is the data? */
netbuf_data( pxRxBuffer, ( void * ) &pcRxString, &usLength );
/* Is this a GET?We don't handle anything else. */
if(( NULL != pcRxString )
&& ( !strncmp( pcRxString, "GET", 3 ) ))
{
/* Update the hit count. */
//ulPageHits++;addr
ulPageHits=pxRxBuffer->ptr->len;
//sendMessage("LwIP: DHCP Started");
//inet_ntoa(*(struct in_addr*)&(netif->ip_addr))
sprintf( cPageHits, "%d", (int)ulPageHits );
/* Write out the HTTP OK header. */
netconn_write( pxNetCon, webHTTP_OK, (u16_t) strlen( webHTTP_OK ), NETCONN_COPY );
/* Generate the dynamic page... First the page header. */
strcpy( cDynamicPage, webHTML_START );
/* ... Then the hit count... */
strcat( cDynamicPage, cPageHits );
//strcat( cDynamicPage, "<p><pre>Task StatePriorityStack #<br>************************************************<br>" );
/* ... Then the list of tasks and their status... */
//vTaskList( ( signed portCHAR * ) cDynamicPage + strlen( cDynamicPage ) );
/* ... Finally the page footer. */
switch(ulPageHits)
{
case 310:gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_1);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_2);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_3);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_4);
break;
case 311 :gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_1);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_2);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_3);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_4);
break;
case 312 :gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_1);
gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_2);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_3);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_4);
break;
case 313 :gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_1);
gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_2);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_3);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_4);
break;
case 314 :gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_1);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_2);
gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_3);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_4);
break;
case 315 :gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_1);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_2);
gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_3);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_4);
break;
case 316 :gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_1);
gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_2);
gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_3);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_4);
break;
case 317 :gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_1);
gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_2);
gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_3);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_4);
break;
case 318 :gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_1);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_2);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_3);
gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_4);
break;
case 319 :gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_1);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_2);
gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_3);
gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_4);
break;
default: gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_1);
gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_2);
gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_3);
gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_4);
break;
}
/*if(ulPageHits<310)
usart_putchar(EXAMPLE_USART, 0);
else if(ulPageHits<319)
{
f=ulPageHits-309;
usart_putchar(EXAMPLE_USART, f);
}
else if(ulPageHits==319)
usart_putchar(EXAMPLE_USART, 0x0a);
*/
/* Write out the dynamically generated page. */
netconn_write( pxNetCon, cDynamicPage, (u16_t) strlen( cDynamicPage ), NETCONN_COPY );
}
netbuf_delete( pxRxBuffer );
}
netconn_close( pxNetCon );
netconn_delete( pxNetCon );
}
#endif
(4)、实现功能
1、强大的越野能力,四路360°舵机强力驱动;
2、电脑、手机对小车的任意控制,无需任何插件、软件;
3、视频的同步监控;
4、数据的传输,可用于野外勘测、数据采集等方面;
5、可加载各种传感器,车上的控制单元都可在不拆卸的情况下直接下载升级。
页:
[1]