移动机器人轨迹跟踪软件设计(站点设计)(DOC)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

燕山大学
课程设计说明书
题目:移动机器人轨迹跟踪软件设计(站点设计)学院(系):电气工程学院
年级专业: 10级过程控制二班
学号:
学生姓名:
指导教师:陈贵林李雅倩
燕山大学课程设计(论文)任务书
2013年11 月25 日
目录
前言……………………………………………………………………………第一章设计思路……………………………………………………………第二章程序……………………………………………………………
第三章算法……………………………………………………………
心得体会
前言
机器人的应用越来越广泛,几乎渗透到所有领域。

移动机器人是机器人学中的一个重要分支。

早在60年代,就已经开始了关于移动机器人的研究。

关于移动机器人的研究涉及许多方面,首先,要考虑移动方式,可以是轮式的、履带式、腿式的,对于水下机器人,则是推进器。

其次,必须考虑驱动器的控制,以使机器人达到期望的行为。

第三,必须考虑导航或路径规划,对于后者,有更多的方面要考虑,如传感融合,特征提取,避碰及环境映射。

因此,移动机器人是一个集环境感知、动态决策与规划、行为控制与执行等多种功能于一体的综合系统。

对移动机器人的研究,提出了许多新的或挑战性的理论与工程技术课题,引起越来越多的专家学者和工程技术人员的兴趣,更由于它在军事侦察、扫雷排险、防核化污染等危险与恶劣环境以及民用中的物料搬运上具有广阔的应用前景,使得对它的研究在世界各国受到普遍关注
关键字:移动机器人
第一章设计思路
1.1 机器人的介绍
机器人的诞生和机器人控制技术发展作为20世纪自动控制原理最具说服力的成就、人类科学技术进步的重大成果[1],是现代计算机与自动化等技术高速发展的产物,同时也是当代最高意义上的自动化。

自1956年第一台工业机器人诞生之日起,机器人的应用越来越普及。

20世纪60年代末机器人开始进入商业化和工业领域以来,机器人的应用范围已经遍及到工业、国防、宇宙空间、海洋开发、医疗保健、抢险救灾等人类生活的各个方面。

机器人由于具有高度的灵活性、快速的反应能力以及巨大的信息处理能力,使其能够在很多环境替代人进行工作。

从重复动作的流水线机械手到智能机器人,从平地到高山海底甚至太空,以至于在比较恶劣危险的工作环境,都是机器人发挥其作用的重要舞台,然而控制系统作为机器人的心脏,其性能的好坏直接决定了机器人的智能化水平。

近年来对移动机器人的研究已成为了一大热点,促进了移动机器人在各个领域中的进一步应用,本文也将在这一方面进行一些分析和研究。

智能移动机器人,是一个集环境感知、动态决策与规划、行为控制与执行等多功能于一体的综合系统。

它集中了传感器技术、信息处理、电子工程、计算机工程、自动化控制工程以及人工智能等多学科的研究成果,代表机电一体化的最高成就,是目前科学技术发展最活跃的领域之一。

随着机器人性能不断地完善,移动机器人的应用范围大为扩展,不仅在工业、农业、医疗、服务等行业中得到广泛的应用,而且在城市安全、国防和空间探测领域等有害与危险场合得到很好的应用。

因此,移动机器人技术已经得到世界各国的普遍关注。

1.2 实训任务分配
本次的设计任务在老师的帮助下得到了细致地划分,而且也增加了一些项目,总体来说任务分为三大块:1.轨迹的识别与跟踪。

2.站的设计。

3.自定义轨迹的运行。

这三部分的任务既是相互独立的又是相互联系的。

首先来分析第一个任务:轨迹的识别与跟踪,这个任务包含了摄像头的初始化以及图像的采集以及图像的存取,轨迹的识别用到了一个算法。

机器人的控制也是这个任务包含的一个总要部分,其中包括了速度控制,方向控制等等。

第二个任务是站的设计,老师提到了“站”这个概念,这是在工厂的生产中的一些重要的机制,也是非常有实用性的一个设计。

第三个任务是自定义轨迹的运行,老师提到了可以设计一个圆形轨迹也可以设计一个方形轨迹,机器人的这种运动在生产生活中的应用也是很广泛的。

1.3 CCD摄像头的介绍
CCD(电荷耦合器)摄像头基本知识
现在科学级的摄像头比前几年更尖端,应用领域也更广了。

在生物科学领域,从显微镜、分光光度计到胶文件、化学放光探测系统,都用到了CCD的摄像头。

但是很多研究工作者对CCD的指标仍云里雾里。

下面对CCD的一些常见指标进行表述。

常见的CCD一般指:CCD摄像头和插在电脑的采集卡区别数字摄像头与模拟摄像头
所有CCD芯片都属于模拟的设备。

当图像进入计算机是数字的。

如果信号在摄像头、采集卡两部分完成数字化的,这个CCD被认为是模拟CCD。

数字摄像头事实上是由内置于摄像头的数字化设备完成数字化过程,这样可以减少图像噪音。

与模拟摄像头相比,数字摄像头提高了摄像头的信噪比、增加摄像头的动态范围、最大化图像灰度范围。

科学级的绝大多数的CCD芯片都是由Kodak、Sony、SIT制造。

评价CCD的基本指标
信噪比SNR真实体现摄像头的检测能力。

所有的CCD摄像头的厂家为提高摄像头的性能,都尽力使信号(可达到满井电子的数目)最大同时尽可能减少噪音。

SNR=满井电子/噪音电子=动态范围=最大灰阶=2bit数
在相同满井电子的CCD,降低CCD噪音,就能提高CCD的监测能力,热或者暗电流对于CCD都是噪音,噪音在Cool CCD基本都可以被深度致冷的Peltier 消除。

在曝光超过5-10秒,CCD芯片就会发热,没有致冷设备的芯片,“热”或者白的像素点就会遮盖图像。

-20度的摄像头可以拍摄不超过5分钟的图像,-40度的摄像头拍摄时间可以超过1小时
1.4机器人从一站到另一站的界面
第二章
2.1定义站点的程序
#if !defined(AFX_DLGSETTING_H__036F7483_B3C7_4494_88D7_5DE026FE694 7__INCLUDED_)
#define
AFX_DLGSETTING_H__036F7483_B3C7_4494_88D7_5DE026FE6947__INCLU DED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DlgSetting.h : header file
//
#include "resource.h"
#include "XPButton.h"
/////////////////////////////////////////////////////////////////////////////
// CDlgSetting dialog
struct Pattern//定义结构体,保存0~99的站点的特征
{
int num; //站点序号
int timer; //停靠时间
BOOL bIsPositive; //滚筒是否正转
BOOL bIsNegative; //滚筒是否反转
};
class CDlgSetting : public CDialog
{
// Construction
public:
CDlgSetting(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CDlgSetting)
enum { IDD = IDD_DIALOG_SETTING };
CComboBox m_ComboLowVel;
CComboBox m_ComboHighVel;
CComboBox m_ComboHandVel;
CComboBox m_ComboRollerNegative;
CComboBox m_ComboRollerPositive;
CComboBox m_ComboStopTime;
CComboBox m_ComboStation;
//按钮美化
CXPButton m_XPbtn_1,m_XPbtn_2,m_XPbtn_3,m_XPbtn_4;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDlgSetting)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CDlgSetting)
virtual BOOL OnInitDialog();
afx_msg void OnBUTTONSaveSpeed();
afx_msg void OnBUTTONSaveStation();
afx_msg void OnCloseupCOMBOStation();
afx_msg void OnButtonPrior();
afx_msg void OnButtonNext();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif
// !defined(AFX_DLGSETTING_H__036F7483_B3C7_4494_88D7_5DE026FE6947 __INCLUDED_)
2.2对于前一站与后一站的定义
/ DlgSetting.cpp : implementation file
//
#include "stdafx.h"
#include "REBotW.h"
#include "DlgSetting.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const int comboStopTime[5] = {0, 2, 15, 30, 40}; //停靠时间,单位:秒
const double comboLowSpeed[5] = {0.50, 0.40, 0.30, 0.20, 0.10}; //低速
const double comboHandSpeed[5] = {1.20, 1.00, 0.80, 0.60, 0.40}; //手动
const double comboHighSpeed[5] = {1.30, 1.20, 1.10, 1.00, 0.80}; //高速
const double g_dAGV_VEL_NORMAL = 8000;//21000; //每秒21000脉冲
double g_dAGV_VEL_LOW;
double g_dAGV_VEL_HAND;
double g_dAGV_VEL_HIGH;
Pattern pStation[100];
/////////////////////////////////////////////////////////////////////////////
// CDlgSetting dialog
CDlgSetting::CDlgSetting(CWnd* pParent /*=NULL*/)
: CDialog(CDlgSetting::IDD, pParent)
{
//{{AFX_DATA_INIT(CDlgSetting)
//}}AFX_DATA_INIT
}
void CDlgSetting::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgSetting)
DDX_Control(pDX, IDC_COMBO_LOW, m_ComboLowVel);
DDX_Control(pDX, IDC_COMBO_HIGH, m_ComboHighVel);
DDX_Control(pDX, IDC_COMBO_HAND, m_ComboHandVel);
DDX_Control(pDX, IDC_COMBO_Roller_negative, m_ComboRollerNegative);
DDX_Control(pDX, IDC_COMBO_Roller_positive, m_ComboRollerPositive);
DDX_Control(pDX, IDC_COMBO_StopTime, m_ComboStopTime);
DDX_Control(pDX, IDC_COMBO_Station, m_ComboStation);
//按钮美化
DDX_Control(pDX, IDC_BUTTON_PRIOR, m_XPbtn_1);
DDX_Control(pDX, IDC_BUTTON_NEXT, m_XPbtn_2);
DDX_Control(pDX, IDC_BUTTON_SaveSpeed, m_XPbtn_3);
DDX_Control(pDX, IDC_BUTTON_SaveStation, m_XPbtn_4);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDlgSetting, CDialog)
//{{AFX_MSG_MAP(CDlgSetting)
ON_BN_CLICKED(IDC_BUTTON_SaveSpeed, OnBUTTONSaveSpeed) ON_BN_CLICKED(IDC_BUTTON_SaveStation, OnBUTTONSaveStation) ON_CBN_CLOSEUP(IDC_COMBO_Station, OnCloseupCOMBOStation) ON_BN_CLICKED(IDC_BUTTON_PRIOR, OnButtonPrior)
ON_BN_CLICKED(IDC_BUTTON_NEXT, OnButtonNext)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgSetting message handlers
BOOL CDlgSetting::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
//打开"站点配置"文件
CFile TheFile("Station.dat",CFile::modeRead);
CArchive ar(&TheFile,CArchive::load,40960);
TheFile.SeekToBegin();
for(int i=0;i<100;i++)
{
ar>>pStation[i].num;
ar>>pStation[i].timer;
ar>>pStation[i].bIsPositive;
ar>>pStation[i].bIsNegative;
CString str;
str.Format(" %d",i);
m_ComboStation.AddString(str);
}
ar.Close();
TheFile.Close();
m_ComboStation.SetCurSel(0);
OnCloseupCOMBOStation();
//打开"速度配置"文件
CFile TheFile2("Velocity.dat",CFile::modeRead);
CArchive ar2(&TheFile2,CArchive::load,40960);
TheFile2.SeekToBegin();
int num_vel;
ar2>>num_vel;
g_dAGV_VEL_LOW = g_dAGV_VEL_NORMAL * comboLowSpeed[num_vel]; //低速m_ComboLowVel.SetCurSel(num_vel);
ar2>>num_vel;
g_dAGV_VEL_HAND = g_dAGV_VEL_NORMAL * comboHandSpeed[num_vel]; //手动m_ComboHandV el.SetCurSel(num_vel);
ar2>>num_vel;
g_dAGV_VEL_HIGH = g_dAGV_VEL_NORMAL * comboHighSpeed[num_vel]; //高速m_ComboHighVel.SetCurSel(num_vel);
ar2.Close();
TheFile2.Close();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CDlgSetting::OnButtonPrior() //前一站
{
if(m_ComboStation.GetCurSel()>0)
{
m_ComboStation.SetCurSel(m_ComboStation.GetCurSel()-1);
OnCloseupCOMBOStation();
}
}
void CDlgSetting::OnButtonNext() //后一站
{
if(m_ComboStation.GetCurSel()<m_ComboStation.GetCount())
{
m_ComboStation.SetCurSel(m_ComboStation.GetCurSel()+1);
OnCloseupCOMBOStation();
}
}
void CDlgSetting::OnCloseupCOMBOStation() //当IDC_COMBO_Station控件发生变化时{
for(int i=0;i<5;i++)
{
if(pStation[m_ComboStation.GetCurSel()].timer == comboStopTime[i])
{
m_ComboStopTime.SetCurSel(i);
}
}
if(pStation[m_ComboStation.GetCurSel()].bIsPositive)
{
m_ComboRollerPositive.SetCurSel(1);
}
else
{
m_ComboRollerPositive.SetCurSel(0);
}
if(pStation[m_ComboStation.GetCurSel()].bIsNegative)
{
m_ComboRollerNegative.SetCurSel(1);
}
else
{
m_ComboRollerNegative.SetCurSel(0);
}
}
void CDlgSetting::OnBUTTONSaveStation() //保存站点设置
{
if(MessageBox("您确定要更改当前的站点设置?","询问",MB_YESNO|MB_ICONQUESTION)==IDYES)
{
pStation[m_ComboStation.GetCurSel()].timer = comboStopTime[m_ComboStopTime.GetCurSel()];
pStation[m_ComboStation.GetCurSel()].bIsPositive = m_ComboRollerPositive.GetCurSel();
pStation[m_ComboStation.GetCurSel()].bIsNegative = m_ComboRollerNegative.GetCurSel();
CFile TheFile("Station.dat",CFile::modeCreate|CFile::modeReadWrite);
CArchive ar(&TheFile,CArchive::store,40960);
TheFile.SeekToBegin();
for(int i=0;i<100;i++)
{
ar<<pStation[i].num;
ar<<pStation[i].timer;
ar<<pStation[i].bIsPositive;
ar<<pStation[i].bIsNegative;
}
ar.Close();
TheFile.Close();
MessageBox("新的站点设置完毕! 下次打开应用软件时有效!","提示",MB_ICONWARNING);
}
}
void CDlgSetting::OnBUTTONSaveSpeed() //保存速度设置
{
if(MessageBox("您确定要更改当前的速度设置?","询问",MB_YESNO|MB_ICONQUESTION)==IDYES)
{
CFile TheFile("Velocity.dat",CFile::modeCreate|CFile::modeReadWrite);
CArchive ar(&TheFile,CArchive::store,40960);
TheFile.SeekToBegin();
ar<<m_ComboLowVel.GetCurSel();
ar<<m_ComboHandVel.GetCurSel();
ar<<m_ComboHighVel.GetCurSel();
ar.Close();
TheFile.Close();
MessageBox("新的速度设置完毕! 下次打开应用软件时有效!","提示",MB_ICONWARNING);
}
}
第三章算法
1 算法目的:
运动目标跟踪算法的目的就是对视频中的图象序列进行分析,计算出目标在每帧图象上的位置。

这里要根据区域分割过程给出的目标质心位置,计算出目标位移,并且根据质心位置的变化判断出目标的运动方向,以及运动目标是否在观察窗口,实现对客流量的统计。

因为该跟踪是对多目标的追踪,需要找出运动目标在相邻帧上的对应区域。

系统具有固有噪声,目标周围背景的干扰可能会产生误差,但这些噪声在前面的过程已经去除,如有必要可做适当调整修正。

2.2 算法难点:
(1)因为要跟踪的是多目标,需要找到相邻帧之间对应的运动目标区域不致跟踪混乱。

(2)如何判断运动目标区域是否是新的目标进入观测窗口
(3)运动目标是否离开了观测窗口以及离开的方向;即计数器何时加1、是否加1
(4)对跟踪过程中出现的一些偏差和问题,要进行必要的修正
2.3 算法描述:
(1)跟踪首先要判断的是:帧与帧之间如何将运动目标对应起来。

追踪过程中的追踪特
征是物体的质心(由运动区域分割过程中给出),这里判断对应目标可以:a.只利用质心间的最短距离做为特征; b.利用加权系数将最短距离,运动目标区域的长度,宽度以及长宽比和面积等综合起来作为特征。

(2)根据判断特征设置目标链,记录每个被跟踪目标的最新质心位置,为下步判断提供条件。

另外将每个目标的质心位置存储起来,可以随时掌握目标的运动情况,为以后要输出目标的运动曲线做基础。

(3)每进入观察窗口一个新的运动目标,就将它的最新质心位置加入该目标链。

如何判断该运动目标是新的:设置门限值ymin,ymax(当ymin<y<ymax视为在观测窗口,当y>ymax或y<ymin可认为是新目标区域),当有目标的质心位置目标.y<ymin或目标.y>ymax并且它的标志位为未被跟踪,则肯定是新目标(在新目标区域出现的目标有可能是要离开观测窗口的目标,不过它们的标志位肯定为被跟踪)。

这样判断出来的新目标方向是有出、入之分的。

(4)与目标链(MB[h][l])相对应的还有位置数组(WZ[m][n]),用来存放目标链中相应目标的质心位置。

最初进行处理时,目标链是空的,在当前帧中若有新目标,则将其横、纵坐标加入到目标链中,并存储在对应的位置数组中,置标记为被跟踪。

(5)处理新的当前帧时,首先将目标链MB中每个元素(代表前一帧中所有运动目标)依次与当前帧中记录的每个运动目标进行距离计算,求出其中最小距离d(假设是MB[i]与当前帧中运动目标t的质心距离)则判断d与门限值λ的大小,若d<λ,则说明运动目标t就是前一祯MB[i]对应的运动目标区域,则将t的质心位置更新代替MB[i]中的横纵坐标(MB[i]中记录目标i的最新质心位置),并将其质心位置加入到WZ[i]中去,记录该目标运动质心的记录,将该运动目标标记为被跟踪;如d>λ则说明该最小值不足以证明它们是对应目标,可能MB[i]代表的目标已经不在跟踪窗口,则做如下处理:
检查对应MB[i]代表的目标质心位置的最新记录,如果MB[i][1](纵坐标)>ymax,可认为目标离开观测窗口,并且方向是进入,则计数器加1;如果MB[i][1]< ymin,目标离开观测窗口,但方向是出去,计数器不动作。

(6)设置数组CC[m][n],存储离开观测窗口并且方向是进入的运动目标质心位置记录,象(5)中的MB[i]若是进入就将对应位置记录WZ[i]存放在数组CC中,同时清除MB[i]中的特征值和WZ[i]中的质心记录。

这里可以另外设置一个空闲位置数组KWZ[i],记录被清空的WZ中的位置,每次有新目标到来,须分配数组空间就先检查是否有被清空的记录。

(7)直至目标链中的目标检查完毕,则查看当前祯中的各运动目标,如有未被标记的,且在新目标区域中则将其加入到目标链中,标记设为已被跟踪。

(8)接收新的当前祯,继续如此处理。

处理过程中可能出现的几个问题为:
(1)如果当前祯中一个运动目标t已经被标记,但是当处理到目标链中下一个目标是最小距离的仍是t,说明目标链中有两个目标都与t的距离最小,这样就需要调整。

(2)如果门限值λ设置不当,则可能产生误判。

(3)如果目标链中所有目标检查完毕,但是在当前祯中有未被标记并且不在新目标区域,
即不是新目标,又不是被跟踪目标的相应目标,则有差错出现,可能是噪声。

(4)是否将离开观测窗口并且运动方向是出去的目标质心位置存储在数组CC 中。

设计心得
为期一个月的专业综合训练马上就要结束了,此次实训我们做的题目是移动机器人轨迹跟踪,简单地说就是通过程序去控制机器人的运动。

实现这个功能主要是通过编写c++程序然后传送到机器人中,控制机器人的运动。

所以此次实训的主要目的就是编写程序然后调试程序。

刚开始的时候,老师就带着我们熟悉编程序的软件,并且告诉我们一定要养成良好的代码风格,并且让我们熟悉掌握外设的初始化和设置,这个是编写程序的基础吧,如果不按照外设初始化和设置的步骤来编写程序,程序就无法正常运行,就算运行了也无法实现正确的功能,所以对于我这个初学者来说,这是很好的经历,可以在调试程序或者是修改程序的时候少走弯路。

老师给我们讲解了许多程序之后,我对编写程序也比较熟练了,然后就是自己把程序下载到机器人芯片上,让机器人跟着轨迹走,根据机器人出现的问题去改正调试程序,最后让机器人可以稳定的运行,以及实现程序控制机器人的目的。

此次实训基本要求实现了,并且锻炼了自己的动手能力,养成了良好的代码风格,对于c++软件也有了一定的了解,可以编写一些简单的程序了,对于我来说这是很大的一个突破。

在实训中编写程序时,学会了看参考手册。

这次实训学到了不少东西,这和我自己的努力有关,这个更离不开老师们的细心指导和教学,在此感谢指导我们一个月的陈贵林老师,你辛苦了,非常感谢。

最后预祝自己明天答辩顺利,成功结束这次专业综合训练。

参考文献
1. 郑阿奇. Visual C++实用教程.北京:电子工业出版社,2012
2. David Simon,周瑜萍等编著.Visual C++6编程宝典.北京:电子工业出版社,
2005
3.肖宏伟编著. Visual C++6.0实效编程百例.北京:人民邮电出版社,2002
燕山大学课程设计评审意见表。

相关文档
最新文档