版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于机器人运动控制系统软件设计(完整资料)(可以直接使用,可编辑优秀版资料,欢迎下载)
基于机器人运动控制系统软件设计基于机器人运动控制系统软件设计(完整资料)(可以直接使用,可编辑优秀版资料,欢迎下载)摘要:移动机器人的运动控制主要是完成移动机器人的运动平台,提供一种移动机器人的控制方式。本文通过对移动机器人的研究,实现了基于渡越时间法的超声波测距模块设计,为机器人提供简单方便的障碍物距离检测。本文主要完成对主控板控制器软件设计、电机驱动控制器软件设计和超声波测距软件的设计,使开发系统能够服务于移动机器人研究的通用开发平台。关键词:机器人;运动控制;软件设计;超声波测距中途分类号:TP9文献标识码:B0引言随着计算机、网络、机械电子、信息、自动化以及人工智能等技术的飞速发展,移动机器人的研究进入了一个崭新的阶段。同时,太空资源、海洋资源的开发与利用为移动机器人的发展提供了广阔的空间。目前,智能移动机器人,无人自主车等领域的研究进入了应用的阶段,随着研究的深入,对移动机器人的自主导航能力,动态避障策略,避障时间等方面提出了更高的要求。地面智能机器人路径规划,是行驶在复杂,动态自然环境中的全自主机器人系统的重要环节,而地面智能机器人全地域全自主技术的研究,是当今国内外学术界面临的挑战性问题.智能移动机器人是一类能够通过传感器感知环境和自身状态,实现在有障碍物的环境中面向目标自主运动,从而完成一定功能的机器人系统。移动机器人技术研究综合了路径规划、导航定位、路径跟踪与运动控制等技术。涉及到包括距离探测、视频采集、温湿度以及声光等多种外部传感器,作为移动机器人的输入信息。移动机器人的运动控制主要是完成移动机器人的运动平台,提供一种移动机器人的控制方式。性能良好的移动机器人运动控制系统是移动机器人运行的基础,能够服务于移动机器人研究的通用开发平台。移动机器人技术研究综合了多学科领域的知识,关键技术可分为:路径规划、导航定位、路径跟踪与运动控制技术。路径规划又可分为全局和局部路径规划.全局路径规划是根据移动机器人总体任务进行路径规划,将总体路径任务分解,并建立全局地形数据库;局部路径规划是根据全局规划分解的子任务,结合移动机器人当前状态信息,实时规划可行路径;导航定位技术确定移动机器人在全局地图中的位置,并实时得到机器人与路径跟踪的相对位置关系,其关键技术是多传感器信息处理与数据融合技术.路径跟踪与运动控制技术的任务是控制移动机器人跟踪局部规划给出的路径,结合导航定位系统得到机器人本身状态信息与道路信息,完成航向和速度控制。移动机器人的路径规划、导航控制以及路径跟踪与运动控制技术是相互关联的,任何一个系统的不完善都会导致整体性能的下降。1主控板软件设计主控板硬件完成模块管理、设备通讯及机器人定位脉冲检测等内容。在实际应用中,主控板硬件还负责超声波测距的软件管理。主控板硬件中只有主控板控制器需要进行软件设计。主控板控制器TMS320LF2407A的主要任务是超声波测距的软件设计管理和其他一些基本设置内容,包括电机码盘的正交编码脉冲检测。初始选定TMS320LF2407A作为主控板控制器是考虑到此控制系统可以作为以后机器人应用的平台,可以在TMS320LF2407A里嵌入实时系统,提升系统性能,方便接口开发。主控板控制器的软件设计内容包括模块初始化、串口通讯、正交编码脉冲检测和超声波测距软件。这里介绍模块初始化串口通讯和正交编码脉冲检测等内容。图1主控板控制器程序流程图。图1主控板控制器程序流程图复位向量地址为程序入口,然后程序进行初始化。初始化内容包括扩展方式、溢出方式、DARAM、倍频、JTAG等基本配置.另外还有使用的相关I/O的设置、程序使用相关定时器的设置、程序使用相关中断的设置和串口通讯的相关设置.这些配置都是控制器使用的基本配置流程。初始化之后会开启相关的中断程序,随后进入超声波测距程序,并一直循环。中断服务程序处于就绪状态,一旦有中断发生,中断服务程序立即执行。在TMS320LF2407A的所有程序中,需要对其串口的数据发送和接收程序做说明.异步通信使用三条线(地线、发送线、接收线)连接采用RS232格式的终端。发送各位依次为一个起始位、l~8个数据位、可选的一个奇偶校验位、1~2个停止位.因此串口通讯能够传输的最大的数据单位为8位,即一个字节。在设计中控制器和各终端会有各种类型的数据交流,如整形数据和浮点数据,因此需要对串口发送和接收的数据进行数据转换。四个字节的单精度浮点数的数据传输,因为串口每次最多只能传输一个字节,所以只需要把每个四字节浮点数的存储数据转换成字节形式发送即可,设计中采用强制转换的方式完成。数据接收的时候也可以采取同样的处理方式,反向转换即可。另外在数据转换上也可选择共用体来实现,共用体的实质和上面讲述的类型转换是一样的,只是共用体的各个数据类型占用的存储空间是共同的,对于这个存储空间,共用体定义的任何结构类型变量都可以调用。上位机里的串口数据处理采用的是这种方法,十分方便.对于正交编码脉冲的检测,TMS320LF2407A具有独立的正交编码脉冲单元,只要对单元寄存器进行简单设置即可得到机器人驱动轮的运行方向和距离参数。TMS320LF2407A将这些数据通过串口发送到上位机,由上位机建模,对数据加以处理后得到机器人的位姿信息.2电机驱动软件设计电机驱动软件完成电机的驱动控制和闭环调速.驱动控制使用的是电机驱动主控芯片STCl2C4052AD的片内PWM外设单元,生成的PWM信号经过电机驱动芯片驱动电机,可以通过调节PWM占空比来调节加载在电机上24VDC电压的占空比,从而调节电机转速.PWM占空比由片内8位的PWM控制寄存器进行控制,该寄存器取值范围为0—255,分别代表PWM信号占空比从l到0的连续变化。同时STCl2C4052AD接收电机光电码盘的脉冲信号,利用片内时钟计算出电机运行速度,通过速度控制算法完成电机的闭环调速。电机驱动及闭环调速软件算法流程图如图2所示。图2电机驱动控制器程序流程图如上图所示,程序开始后进行初始化,初始化包括程序使用相关变量定义、10ms定时器0、定时器l及串口、脉冲计数用外中断0、看门狗等寄存器的设置和电机状态参数(刹车、速度)等的初始化。然后进入循环状态,循环过程中更新看门狗寄存器的相关标志位.速度检测和闭环调速程序分别在外中断0和定时器0中完成。中断服务程序也就包含了外中断0、定时器0以及串口中断服务程序.外中断0是电机光电码盘的脉冲检测外设,所有电机光电码盘的脉冲都会引起外中断0的中断。码盘脉冲测速的原理是计算STCl2C4052AD单位定时时间内的脉冲数目,因此外中断0的中断服务程序的内容就是对脉冲计数.而上位机设定的目标电机转速也会被转换为此单位定时时间内的脉冲数目。可以定义一个全局变量,每次进入外中断0的中断将该变量加1即可。另外为防止程序干扰,应该对计数值加以修正,如小于0的时候等于0,大于某一设定值的时候等于某一设定值等.3超声波测距软件设计设计中的超声波测距软件利用了常用超声波测距的渡越时间法.渡越时间法的工作原理为发射超声波的同时开始计时,接收到超声波后停止计时,记录超声波的传输时间为t,那么超声波测距模块和障碍物的距离为s由下式表示。S=v*t/2其中v为超声波在空气中的传播速度。由下式表示。其中,T为空气的华氏温度。在常温下,超声波的传输速度随温度变化并不太大,而且超声波的传输时间都为毫秒级,因此影响不是很大。不过也可以为超声波测距模块添加一个温度校正模块,检测环境温度,再在主控板控制器计算超声波速度时进行修正。现在市场已有集成温度检测器件,也很方便。超声波测距的主要流程为发射超声波以后,如果有反射超声波信号返回,则由外中断0接收计算距离.在超声波信号发射的同时打开定时器3,定时时间为最大超声波测量距离所需的传输时间,如果在定时器3中断的时候还没有外中断0中断事件发生,即没有反射超声波信号返回,那么在进入定时器3中断的时候关闭超声波返回中断和超声波传输时间定时器l,进行下一次的超声波测距循环。程序流程图如图3所示。图3超声波测距程序流程图外中断0接收到超声波测距信号返回,则进入外中断0服务程序进行测距程序处理。若没有超声波信号返回则将发生定时器3的定时中断,说明等待超时,设定测距范围内无障碍物.两种情况都将引发等待标志位的改变,程序跳出等待状态,更改工作超声波测距模块,进行下一个超声波模块的测距处理。外中断0和定时器0的程序流程图如图4所示.图4外中断0和定时器3程序流程图图中A为外中断0程序流程图。进入中断服务程序表示有超声波信号返回。程序开始关闭所有系统的可屏蔽中断和测距使用外设,读取定时器l计数值,计算障碍物距离。更改程序循环标志,然后中断服务程序返回。B为定时器3的程序流程图。进入中断服务程序表示测距范围内无障碍物,因此只用关闭系统的可屏蔽中断和测距使用外设,直接更改程序循环标志,退出中断服务程序即可。设置定时器1不产生中断,而设置定时器1为定时最大值也不会发生定时器l中断。因此不必写定时器1的中断服务程序。4结论本主控板控制器协调上位机和各模块的工作,软件设计中详细讲述串口传输中的数据类型处理问题。利用单片机PWM外设生成脉冲宽度调制信号驱动电机,并通过光电码盘实现电机的闭环调速。超声波测距模块已经有广泛的应用,超声波测距模块软件程序采用通用的渡越时间法完成距离的测量,并通过模拟开关实现多超声波测距模块的分时工作。基于Android的智能聊天机器人的设计与实现学院名称:专业:班级:学号:姓名:任课教师:安卓智能聊天机器人开发(一)这个聊天机器人有点像前段时间很火的一个安卓应用-—小黄鸡应用的实现其实很简单,网上有许多关于智能机器人聊天的接口,我们只需要去调用对应的接口,遵守它的API开发规范,就可以获取到我们想要的信息这里我使用的接口是——图灵机器人(http://www.tuling123.com/openapi/)这个接口给我们返回的是Json字符串,我们只需要对它进行Json字符串解析,就可以实现这个应用。
开发步骤:首先我们需要到这个图灵机器人的官网去注册一个账号,他会给我们一个唯一Key,通过这个Key和对应的API开发规范,我们就可以进行开发了.
然后在这个(http://www。tuling123.com/openapi/cloud/access_api.jsp)网址里可以找到相关的开发介绍比如:请求方式,参数,返回参数,包括开发范例,一些返回的编码等信息这里是官方提供的一个调用小案例(JAVA),这里我也顺带贴一下/**调用图灵机器人平台接口*需要导入的包:commons-logging—1.0.4。jar、httpclient-4.3。1.jar、httpcore-4.3.jar*/publicstaticvoidmain(String[]args)throwsIOException{StringINFO=URLEncoder。encode("北京今日天气","utf—8");Stringrequesturl="http://www.tuling123。com/openapi/api?key=注册激活返回的Apikey&info="+INFO;HttpGetrequest=newHttpGet(requesturl);HttpResponseresponse=HttpClients。createDefault()。execute(request);//200即正确的返回码if(response.getStatusLine().getStatusCode()==200){Stringresult=EntityUtils。toString(response.getEntity());System.out.println("返回结果:”+result);}}
好了,接下来开始实战吧,这个应用我打算写成两篇文章第一篇讲下关于如何调用接口,从网上获取数据,包括解析Json字符串第二篇会把这些获取的数据嵌入到安卓应用
首先,先写一个工具类,这个工具类是用来获取用户输入的信息并返回服务器提供的数据的这里面用到了一个第三方提供的JAR包,Gson它是谷歌提供给我们用来使Json数据序列化和反序列化的关于Gson的使用我之前写过一篇笔记,不熟悉的朋友可以看看:Gson简要使用笔记(http://wblogs.com/lichenwei/p/3987429.html)代码如下:具体看注释packagecom.example。utils;importjava.io.ByteArrayOutputStream;importjava。io.IOException;importjava.io.InputStream;importjava.io.UnsupportedEncodingException;importjava.net.HttpURLConnection;importjava。net。MalformedURLException;importjava.net。URLEncoder;importjava.util.Date;importandroid.util.Log;importcom。example.pojo.Message;importcom。example。pojo.Message.Type;importcom。example.pojo。Result;importcom.google.gson.Gson;/****获取信息帮助类传入用户输入的字符,给出相对应的信息**/publicclassGetDataUtils{privatestaticfinalStringAPI_KEY=”这里填写官方提供的KEY”;//申请的API_KEY值privatestaticfinalStringURL=”http://www.tuling123.com/openapi/api";//接口请求地址publicStringgetChat(Stringmsg){//这个方法是获取服务端返回回来的Json数据,msg为用户输入的信息Stringresult="";//存放服务器返回信息的变量InputStreaminputStream=null;ByteArrayOutputStreamoutputStream=null;try{//进行资源请求java.net。URLurl=newjava.net。URL(getMsgUrl(msg));HttpURLConnectionhttpURLConnection=(HttpURLConnection)url。openConnection();//打开资源连接//HttpURLConnection参数设定httpURLConnection.setReadTimeout(5*1000);httpURLConnection.setConnectTimeout(5*1000);httpURLConnection。setRequestMethod(”GET");inputStream=httpURLConnection.getInputStream();//获取一个输入流接收服务端返回的信息intlen=-1;byte[]bs=newbyte[124];//用来接收输入流的字节数组outputStream=newByteArrayOutputStream();//用一个输出流来输出刚获取的输入流所得到的信息while((len=inputStream.read(bs))!=—1){//从输入流中读取一定数量的字节,并将其存储在缓冲区数组//bs中outputStream.write(bs,0,len);//往输入流写入}outputStream。flush();//清除缓冲区result=newString(outputStream。toByteArray());//转换成字符串}catch(MalformedURLExceptione){e。printStackTrace();}catch(IOExceptione){e。printStackTrace();}finally{//关闭相关资源if(inputStream!=null){try{inputStream。close();}catch(IOExceptione){e.printStackTrace();}}if(outputStream!=null){try{outputStream。close();}catch(IOExceptione){e。printStackTrace();}}}Log.i(”tuzi","result:”+result);//打印测试日志returnresult;}privateStringgetMsgUrl(Stringmsg)throwsUnsupportedEncodingException{Stringpath="";Stringinfo=URLEncoder。encode(msg,"UTF—8”);//转换url编码path=URL+"?key=”+API_KEY+”&info=”+msg;returnpath;}publicMessagegetInfo(Stringmsg){Messagemessage=newMessage();Gsongson=newGson();try{Resultresult=gson.fromJson(getChat(msg),Result。class);//获取到服务器返回的json并转换为Result对象,Result对象可能不存在,会出现异常message.setMsg(result.getText());//message可能为空,需要捕获异常}catch(Exceptione){//可能服务器没有返回正常数据,也就存在着空白内容,需要捕获异常message.setMsg("服务器繁忙,请稍后再试”);}message.setTime(newDate());message.setType(Type。INCOME);returnmessage;}}下面这2个是实体类,根据官网提供的示例,返回的Json字符串里包含:code状态码,text文本内容packagecom.example.pojo;/****用来映射返回Json字符串**/publicclassResult{privateStringcode;privateStringtext;publicStringgetCode(){returncode;}publicvoidsetCode(Stringcode){this。code=code;}publicStringgetText(){returntext;}publicvoidsetText(Stringtext){this.text=text;}}packagecom.example.pojo;importjava.util.Date;publicclassMessage{privateStringname;privateStringmsg;privateDatetime;privateTypetype;publicenumType{//类型枚举,发送,接收INCOME,OUTCOME}publicStringgetName(){returnname;}publicvoidsetName(Stringname){t=name;}publicStringgetMsg(){returnmsg;}publicvoidsetMsg(Stringmsg){this。msg=msg;}publicDategetTime(){returntime;}publicvoidsetTime(Datetime){this。time=time;}publicTypegetType(){returntype;}publicvoidsetType(Typetype){this.type=type;}}编写个测试类packagecom。example。test;importandroid.test。AndroidTestCase;importandroid。util.Log;。example。pojo。Message;importcom。example。utils。GetDataUtils;publicclassGetDataUtilsTestextendsAndroidTestCase{publicvoidtest(){GetDataUtilsdataUtils=newGetDataUtils();Messagemessage=dataUtils.getInfo(”你好");Messagemessage1=dataUtils.getInfo(”你是谁”);Messagemessage2=dataUtils.getInfo(”你知道JAVA是什么吗");Messagemessage3=dataUtils.getInfo(”下雨了,天好冷");Log.i("兔子",message.getMsg());Log.i("兔子”,message1.getMsg());Log。i("兔子",message2.getMsg());Log.i("兔子",message3.getMsg());}}在JAVAWEB里编写测试单元用到的是Junit,需要导入jar包,在安卓开发里也有类似这样的步骤首先我们要在AndroidManifest。xml里的application标签里添加<uses—libraryandroid:name="android.test。runner"/>然后在application外添加<instrumentationandroid:name=”android.test.InstrumentationTestRunner"android:label="ceshi”android:targetPackage=”com。example.androidchat”>〈/instrumentation>由于需要联网别忘了给应用赋予网络权限〈uses-permissionandroid:name="android。permission.INTERNET"/>这里是完整文件代码:<?xmlversion=”1.0”encoding="utf—8"?>〈manifestxmlns:android="http://schemas。androi/apk/res/android”package="com。example.androidchat"android:versionCode="1”android:versionName="1.0”>〈uses-sdkandroid:minSdkVersion="8”android:targetSdkVersion="21”/〉<uses—permissionandroid:name="android.permission.INTERNET”/〉<applicationandroid:allowBackup="true”android:icon=”@drawable/ic_launcher"android:label=”@string/app_name"android:theme=”@style/AppTheme"〉〈uses-libraryandroid:name="android。test。runner"/〉<activityandroid:name=".MainActivity"android:label="@string/app_name"><intent-filter><actionandroid:name=”android。intent.action。MAIN"/><categoryandroid:name="andrent.category.LAUNCHER"/></intent-filter〉</activity〉</application〉〈instrumentationandroid:name=”android.test.InstrumentationTestRunner"android:label="ceshi"android:targetPackage="com.example.androidchat”〉</instrumentation>〈/manifest〉看下我们的测试代码效果图:
好了,此时我们已经可以获取到服务端的数据,并且接收到客户端并做处理在上一篇文章中,已经实现了对网络数据的获取和处理封装,这篇文章来讲下如何嵌入到安卓应用中.先看下效果图:从上面两张图我们可以发现,这个聊天布局其实就是一个ListView,只不过它和传统的ListView有些区别,因为它使用了多Item样式布局首先,先来分析下基础布局:这个界面是由3个布局文件组成,分别是主布局,发送消息样式布局,接收消息样式布局先来看下主布局:这里是对应的主布局代码:android:divider="@null"--去除ListView的Item分割线〈RelativeLayoutxmlns:android="http://schemas.andro/apk/res/android"xmlns:tools=”http://schemas。android.com/tools"android:layout_width="match_parent"android:layout_height=”match_parent”android:background="@drawable/chat_bg_default">〈LinearLayoutandroid:id="@+id/title”android:layout_width=”fill_parent"android:layout_height="wrap_content"android:layout_alignParentTop=”true”android:background="@drawable/title_bar"android:gravity="center"android:orientation=”vertical”〉<TextViewandroid:layout_width=”wrap_content"android:layout_height="fill_parent"android:layout_gravity=”center”android:text="机器兔"android:textColor="@android:color/white”android:textSize="20sp"/〉</LinearLayout>〈RelativeLayoutandroid:id="@+id/bottom"android:layout_width=”fill_parent"android:layout_height=”55dp"android:layout_alignParentBottom="true”android:background=”@drawable/bottom_bar"android:padding=”5dp"><EditTextandroid:id=”@+id/send_message”android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_centerVertical=”true"android:layout_marginLeft="5dp”android:layout_marginRight="5dp"android:background="@drawable/login_edit_normal"/><Buttonandroid:id="@+id/send_bt"android:layout_width="wrap_content”android:layout_height=”fill_parent"android:layout_alignParentRight="true"android:layout_alignRight="@id/send_message"android:background=”@drawable/send_button_selector”android:gravity=”center_vertical”android:text="发送”/>〈/RelativeLayout>〈ListViewandroid:id="@+id/chatlistview"android:layout_width="fill_parent”android:layout_height="fill_parent”android:layout_above=”@id/bottom"android:layout_below=”@id/title”android:divider="@null"〉〈/ListView></RelativeLayout>再来看下消息布局:(由于消息布局只是左右两边方向的不同,这里只给出其中一个)这是2个消息布局的代码:〈?xmlversion="1。0”encoding="utf-8”?>〈LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width=”match_parent"android:layout_height="match_parent"android:orientation=”vertical”>〈TextViewandroid:id="@+id/sendtime”android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity=”center”android:background="#999999”android:text="2014—11-0718:00"android:textColor=”@android:color/white”/>〈LinearLayoutandroid:layout_width="match_parent"android:layout_height=”wrap_content”android:orientation="horizontal">〈LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical”〉<!-—头像昵称部分-—><ImageViewandroid:layout_width=”50dp”android:layout_height=”50dp"android:src=”@drawable/icon1"/><TextViewandroid:layout_width=”wrap_content"android:layout_height=”wrap_content"android:layout_gravity="center"android:text="机器兔"/></LinearLayout〉〈TextViewandroid:id="@+id/sendmsg”android:layout_width=”wrap_content”android:layout_height="wrap_content"android:background=”@drawable/chatfrom_bg_normal”android:text="你好,我是机器兔。"/〉</LinearLayout〉</LinearLayout><?xmlversion=”1。0"encoding=”utf—8”?>〈LinearLayoutxmlns:android="http://schemas。android.com/apk/res/android"android:layout_width="match_parent"android:layout_height=”match_parent"android:orientation=”vertical"〉〈TextViewandroid:id="@+id/receivetime"android:layout_width="wrap_content"android:layout_height=”wrap_content"android:layout_gravity=”center”android:background=”#999999”android:text=”2014—11—0718:00"android:textColor="@android:color/white"/><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="wrap_content”android:gravity=”right"android:orientation=”horizontal"><TextViewandroid:id="@+id/receivemsg"android:layout_width="wrap_content"android:layout_height="wrap_content”android:background=”@drawable/chatto_bg_normal”android:text=”你好,我是机器兔。”android:textColor="@android:color/black"/〉<LinearLayoutandroid:layout_width=”wrap_content"android:layout_height=”wrap_content”android:orientation="vertical">〈!--头像昵称部分--〉<ImageViewandroid:layout_width="50dp"android:layout_height="50dp”android:src=”@drawable/icon"/>〈TextViewandroid:layout_width="wrap_content"android:layout_height=”wrap_content”android:layout_gravity="right”android:text=”我"/>〈/LinearLayout></LinearLayout></LinearLayout〉接下来看下关于ListView的自定义适配器,和往常一样自定义适配器需要继承BaseAdapter,并实现一些必须的方法这里有个需要注意的是,因为传统的ListView是统一一个样式的,而这里的聊天布局是左右两边收发信息多Item样式所以需要额外的多覆写2个方法:1、getViewTypeCount--返回样式的种类数目2、getItemViewType
--给定类型标示符,便于在回调函数getView时让系统知道我们需要显示的哪个样式代码里还提到了ViewHolder,这个是优化ListView加载速度的一种方法,关于这个知识点我整理一篇笔记《安卓开发笔记——ListView加载性能优化ViewHolder》出来,不熟悉的朋友可以看看。packagecom。example.androidchat;importjava.text.SimpleDateFormat;importjava.util。List;importcom。example.pojo。Msg;imp。example。pojo.Msg。Type;importandroid.content。Context;importandroid.view.LayoutInflater;importandroid。view。View;importandroid.view。ViewGroup;importandroid.widget。BaseAdapter;importandroid.widget.TextView;/****ListView适配器**/publicclassChatAdapterextendsBaseAdapter{privateList〈Msg>data;privateLayoutInflaterinflater;//布局工厂,可以把res/layout的xml布局文件转换成view对象publicChatAdapter(Contextcontext,List〈Msg>data){inflater=LayoutInflater。from(context);this。data=data;}@OverridepublicintgetCount(){returndata.size();}@OverridepublicObjectgetItem(intposition){returndata.get(position);}@OverridepubliclonggetItemId(intposition){returnposition;}@OverridepublicViewgetView(intposition,ViewconvertView,ViewGroupparent){Msgmessage=data.get(position);ViewHolderviewHolder=null;if(convertView==null){//未加载布局文件对象//可以通过getItemViewType所定义的标识来设定对应的item样式if(getItemViewType(position)==0){//接收信息viewHolder=newViewHolder();convertView=inflater.inflate(R.layout.send_msg,null);viewHolder。time=(TextView)convertView.findViewById(R。id。receivetime);viewHolder.msg=(TextView)convertView。findViewById(R。id.receivemsg);}else{viewHolder=newViewHolder();convertView=inflater.inflate(R.layout。receive_msg,null);viewHolder.time=(TextView)convertView。findViewById(R。id.sendtime);viewHolder。msg=(TextView)convertView。findViewById(R。id.sendmsg);}convertView.setTag(viewHolder);}else{//已经存在布局文件对象viewHolder=(ViewHolder)convertView.getTag();}//设置数据SimpleDateFormatdateFormat=newSimpleDateFormat(”yyyy-MM-ddHH:mm:ss”);viewHolder。time.setText(dateFormat.format(message。getTime()));viewHolder。msg。setText(message.getMsg());returnconvertView;}/***由于此处我们要返回2种ListView的Item样式,需要再额外多覆写2个方法*(1)、getItemViewType(intposition)给定类型标示符*(2)、getViewTypeCount()类型数量*/@OverridepublicintgetItemViewType(intposition){Msgmessage=data。get(position);if(message。getType()==Type。INCOME){return0;//如果消息类型为接收,则值为0}return1;//如果消息类型为发送,则值为1}@OverridepublicintgetViewTypeCount(){return2;}privatefinalclassViewHolder{TextViewtime;//消息时间TextViewmsg;//消息内容}}然后就是主程序代码了:这里就没什么好说的了,网络数据获取工具类包括ListView的适配器类在之前已经提过,这里就只剩下调用了。注意点有3:1、那就是在UI主线程里不能直接取获取网络数据,这里我们需要另开一个子线程去获取,然后在通过Handler去更新UI界面。2、当数据源发生更新的时候,需要在UI主线程去操作,而不是子线程,还有就是不应该去重新设置Adapter,只需要去调用Adapter的notifyDataSetChanged()就行。3、记得设置下ListView的setSelection选项,便于焦点自动往下拉.不在UI主线程里做耗时操作,会使得UI现成阻塞.不在子线程里去更新UI界面,会导致应用程序无响应。packagecom.example.androidchat;importjava.util.ArrayList;importjava。util.Date;importjava.util。List;importandroid.app.Activity;importandroid.os.Bundle;importandroid.os。Handler;importandroid。os.Message;importandroid。view.View;importandroid.view。View.OnClickListener;importandroid.widget.Button;importandroid。widget.EditText;importandroid。widget.ListView;importcom.example。pojo。Msg;importcom。example.pojo.Msg。Type;importcom.example.utils.GetDataUtils;publicclassMainActivityextendsActivity{privateListViewlistview;privateEditTextsendmsg;privateButtonsendbt;privateChatAdapteradapter;//ListView自定义适配器privateList<Msg>data;//数据源privateHandlerhandler=newHandler(){publicvoidhandleMessage(Messagemsg){MsgreceiveMsg=(Msg)msg。obj;data.add(receiveMsg);adapter。notifyDataSetChanged();listview.setSelection(data。size()-1);//定位位置,自动下拉};};@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R。layout.activity_main);initView();//初始化控件initData();//初始化数据initAction();//初始化事件}privatevoidinitAction(){this.sendbt.setOnClickListener(newOnClickListener(){@OverridepublicvoidonClick(Viewv){/***点击发送按钮执行步骤*1、获取用户输入的内容并显示到ListView(判断是否为空)*2、发送用户输入的内容到服务端获取服务端返回内容并显示到ListView(注意线程处理)*3、清空输入框*/finalStringsendInfo=sendmsg.getText()。toString();//获取用户输入数据(用于发送)data.add(newMsg(”",sendInfo,newDate(),Type。INCOME));adapter。notifyDataSetChanged();//更新数据源listview。setSelection(data.size()-1);//定位位置,自动下拉sendmsg.setText(”");//向服务端发送信息并接收返回信息,由于UI主线程不能执行网络获取操作,这里需要开一个子线程newThread(){@Overridepublicvoidrun(){//执行网络操作GetDataUtilsdataUtils=newGetDataUtils();Msgmsg=dataUtils。getInfo(sendInfo);//获取到一个Msg对象,但由于子线程不能够更新UI,所以需要用到一个HandlerMessagemessage=Message。obtain();message.obj=msg;//封装信息handler.sendMessage(message);}}.start();}});}privatevoidinitData(){data=newArrayList<Msg>();adapter=newChatAdapter(MainActivity。this,data);//获取ListView适配器实例listview。setAdapter(adapter);}privatevoidinitView(){this.listview=(ListView)MainActivity.this.findViewById(R.id。chatlistview);this.sendmsg=(EditText)findViewById(R。id。send_message);this.sendbt=(Button)findViewById(R。id。send_bt);}}现场总线基于CAN总线的自动门控制系统设计系部专业班级学生姓名指导教师2015年6月15日课程设计(论文)任务书题目名称基于CAN总线的自动门控制系统设计学生学部(系)专业班级姓名学号课程设计(论文)的内容设计一个监控系统,用AT8952单片机和现场总线技术实现基于CAN总线的监控系统,进而进行相应的硬件电路的设计并进行软件的设计。课程设计(论文)的要求与数据1。用AT89S52单片机和现场总线技术;2。推广嵌入应用于各种测控领域;三、课程设计(论文)应完成的工作1.完成硬件和软件设计,绘出相关原理图;2.完成课程设计报告的撰写。四、课程设计(论文)进程安排序号设计(论文)各阶段内容地点起止日期1收集单片机等相关资料,确定设计方案校内2015年6月20日2进行硬件和软件设计,绘出相关原理图校内2015年6月21-25日3进行课程设计报告的撰写校内2015年6月26、27日五、应收集的资料及主要参考文献1.收集设计中所涉及的主要器件等方面的资料2。收集相关的软件方面的资料发出任务书日期:2015年6月1日指导教师签名:计划完成日期:2015年6月27日教学单位责任人签章:目录TOC\o”1-3”\h\z\uHYPERLINK\l”_Toc314068513"1设计思路和整体规划思路12设计内容3HYPERLINK\l”_Toc314068513”2.1提要3HYPERLINK\l”_Toc314068513"2.2概念3HYPERLINK\l"_Toc314068513”2。3意义32。4原理图33系统硬件设计33.1CAN介绍33。2硬件组成结构3HYPERLINK\l”_Toc314068513"3。3模块上线5参考文献6基于can总线的自动门控制系统的设计黎信威杜腾波潘绍洲摘要:本设计介绍了一种基于CAN总线的自动门控制系统,本设计采用AT89S52单片机,独立CAN控制器SJA1000.自动门控制系统软件设计主要有开门程序和关门程序。当门前1米有人或按开门按钮时,热释电红外人体传感器检测到信号后传给单片机,当两对管都未检测到信号时停止开门,此时如果继续有人来则继续开门。如果无人在感应区内移动,则执行关门程序,当突然有夹人信号,则门立即全部打开,防止夹人事故的发生.如果没有人在门中间或在门口移动,则重新执行关门程序,最后两扇门完全关闭.由于热释电红外传感器在检测到有人移动开门后,会自动延时3-4秒,因此,在软件上不必再设置延时程序。关键字:CAN总线自动门控制系统AT8952单片机1设计思路和整体规划思路自动门的控制主要基于硬件和软件的要求,硬件方面采用简单高效的51单片机系统板来实现还有就是直流电机,红外对管传感器,热释电型红外传感器,软件方面基于单片机设计。自动门的门板由支架支撑在导轨上,导轨连接到驱动装置,驱动装置通过皮带来带动门板在导轨内滑动。电动门的驱动装置是一组电机组件,由直流电机来完成。主控制器单片机是自动门的指挥中心,通过内部指令程序,发出相应指令,指挥电机工作。外部信号由热释电型红外传感器来完成,当有移动的物体进入它的工作范围时,它就给主控制器单片机一个信号,电机提供开门与关门的主动力。然后开门。自动门门扇完成一次开门与关门的工作流程如下:感应探测器将探测信号传至主控制器单片机上,主控制器判断后控制电机运行。电机得到一定运行电流后做正向运行,将动力经传动机构使自动门扇开启;自动伸缩门扇开启后由控制器做出判断,控制电机作反向运动,关闭自动门扇。在双开门上两边分别安装红外对管,当门打开的过程中,又有人过来时,人流量增大,此时,红外对管的接收器不能接收到发射器的信号,把情况传输给主控制器单片机上,然后再由单片机控制电机将门打开。在双开的门棱上安装一组红外对管,当门在关的过程中有人或物时,表示有夹物情况出现,红外对管的接收器将不能接收到发射器的信号,并把情况传输给主控制器单片机上,然后再由单片机控制电机将门打开。同时,在门的两侧,可安装按钮,直接控制直流电机.当控制器系统出现故障时,也可由人人为的主动按按钮,达到在系统出现故障时,人也可以自如的开进门的状况。系统基本流程如下:51单片机51单片机红外传感器电机开门来人关门无人开始有夹物红外对管无夹物直接关门结束手动按按钮人流量(多)2实验内容2.1提要本实验利用CAN模块检测光电开关的信号及步进电机的起、停和方向控制,通过实验平台上的步进电机模拟电动门,光电开关信号来模拟实现人的进出。利用组态软件编写一上位机软件,实现对光电开关的检测及电机的控制.2.2概念自动门根据使用的场合及功能的不同可分为自动平移门、自动平开门、自动旋转门、自动圆弧门、自动折叠门等,其中自动平移门使用得最广泛,我们通常所说的自动门、感应门就是指自动平移门.2.3意义自动平移门最常见的结构形式是自动门机械驱动装置和门内外两侧红外线,当人走近自动门时,红外线感应到人的存在,给控制器一个信号,控制器通过驱动装置将门打开.当人通过门之后,再将门关闭。由于自动门在通电后可以实现无人看管,同时又可节约空调能源、防风、防尘、降低噪音,提高了建筑的档次。2.4原理图系统的整体原理图3系统硬件设计3.1CAN介绍CAN系统:基于CAN协议的CAN总线分布式数据采集网络,主要用于实现CAN总线应用中的通信控制和数据采集方案。CAN协议是一种基于连接的CAN应用层协议,是整个CAN系统的基础与核心。制定CAN协议的思路源于为中国中小型CAN应用网络提供一种简单、可靠、稳定的应用层协议。在充分汲取了DeviceNet协议和CANopen协议之精萃的基础上,优先保障通信数据的可靠性与实时性,以相对简单的方式进行数据通信,从而有效降低了硬件实现成本,这就是CAN协议的巨大优势.3.2硬件组成结构系统组成如图1所示,系统的控制台由PC机和CAN总线适配卡等组成;CAN节点主要由单片机、CAN控制器和CAN收发器组成。该实验主要利用iCAN4050模块控制传动系统的运动方向及起、停控制。iCAN4050模块功能:CAN—4050DI/DO功能模块用于采集开关量输入信号,并提供开关量输出信号.CAN-4050DI/DO功能模块具有8路开关量输入通道和8路开关量输出通道。CAN-4050DI/DO功能采用CAN总线通讯接口,符合CAN2.0B协议规范。模块在工作时,将输入的电压型开关量信号或者无源触点信号经过调理以后,送入单片机进行处理,通过CAN总线通讯将输入的开关量信号状态传送到网络中的主控设备,并且主控设备通过CAN总线将输出的开关量状态传送到模块。CAN-4050DI/DO功能模块采用表面安装工艺,大大提高了系统在恶劣环境中使用的可靠性.CAN-4050DI/DO功能模块的底座上配有导轨架,可以直接安装在标准的DIN导轨上,用户也可以采用其它的简便的安装方式。参数:电源具有极性反接保护功能模块电源:单电源供电,供电电压为+10V~+30VDCCAN控制器:PHILIPSSJA1000CAN收发器:PHILIPSPCA82C251通讯协议:符合CAN协议规范V2.0B版工作环境温度:-20℃~+85℃
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年版的软件购买与技术支持合同
- 服装销售店长下半年工作计划10篇
- 春季工作计划模板8篇
- 2025年度全球十大风险报告
- 创建文明城市倡议书范文合集九篇
- 员工辞职申请书汇编6篇
- 2025年高模量玻璃纤维布项目发展计划
- 新安江生态补偿报告
- 煤业企业调度室管理制度汇编
- 计划生育-妇产科教学课件
- 数据中心电力设备调试方案
- 2024年度国际物流运输合同3篇
- 新入职员工年终工作总结课件
- 重庆市2025届高三上学期12月一诊模拟考试英语读后续写翻译练习(接受新生命)(含答案)
- 广西南宁市第三十七中学2024-2025学年七年级上学期11月第一次月考语文试题(含答案)
- 2024-2025学年高二上学期期末数学试卷(基础篇)(含答案)
- 汽车吊篮使用专项施工方案
- 静脉导管维护
- 普通逻辑学智慧树知到期末考试答案章节答案2024年河海大学
- 带你听懂中国传统音乐智慧树知到期末考试答案2024年
- 年度先进员工选票标准格式
评论
0/150
提交评论