机器人技术与实践第四章:Boe-Bot 机器人巡航控制与触觉导航_第1页
机器人技术与实践第四章:Boe-Bot 机器人巡航控制与触觉导航_第2页
机器人技术与实践第四章:Boe-Bot 机器人巡航控制与触觉导航_第3页
机器人技术与实践第四章:Boe-Bot 机器人巡航控制与触觉导航_第4页
机器人技术与实践第四章:Boe-Bot 机器人巡航控制与触觉导航_第5页
已阅读5页,还剩64页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第四章Boe-Bot机器人巡航控制与触觉导航第一节Boe-Bot机器人巡航控制一、基本的机器人动作

图4-1规定了机器人的前后左右四个方向,当机器人向前走时,它的左轮会逆时针旋转,而右轮则顺时针旋转,4-1Boe-Bot机器人及其驱动方向指示

当机器人向前走时,它的左轮会逆时针旋转,而右轮则顺时针旋转。如果还没有领会这一点,观察一下图4-2,看能否使自己相信这是真的。从机器人的左边看,当它向前走时轮子是逆时针旋转的;从右边看另一个轮子则是顺时针旋转的。

图4-2向前运动时两个轮子的旋转

回忆一下前面内容,PULSOUT命令的参数Duration控制了伺服电机旋转的速度和方向。FOR…NEXT循环的参数StratValue和EndValue控制传递给电机的脉冲数量。由于每个脉冲的时间是相同的,因而EndValue也控制伺服电机运行的时间。这个例子使机器人向前走三秒钟。程序示例:'RoboticswiththeBoe-Bot-BoeBotForwardThreeSeconds.bs2'MaketheBoeBotrroolforwardforthreeseconds'{$STAMPBS2}'{$PBASIC2.5}DEBUG"ProgramRunning!:"counterVARWordFREQOUT4,2000,3000'Signalprogramstart/reset.FORcounter=1TO122'Runservosfor3secondsPULSOUT13,850PULSOUT12,650PAUSE20NEXTEND

该程序使机器人向前走了3秒钟我们可以通过修改程序中的参数值,改变机器人的运行时间,并将PULSOUT命令中的Duration参数值进行修改,看看机器人的运行速度,并以不同的组合实现机器人的行走不同方向,如向前、原地转弯、绕轴转弯等。PULSOUT13,650PULSOUT12,850向后走PULSOUT13,650PULSOUT12,750PULSOUT13,750PULSOUT12,850原地左转原地右转该你了调节距离和速度

将FOR…NEXT循环的EndValue参数值由122调到61,使机器人运行时间是刚才的一半,运行距离也是一半。程序示例,我们将各个方向组合在一起,命令机器人行走。'RoboticswiththeBoe-Bot-ForwardLeftRightBackward.bs2'Moveforward,left,right,thenbackwardfortestingandtuning.'{$STAMPBS2}'{$PBASIC2.5}DEBUG"ProgramRunning!:"counterVARWordFREQOUT4,2000,3000'Signalprogramstart/reset.FORcounter=1TO64'ForwardPULSOUT13,850PULSOUT12,650PAUSE20NEXTPAUSE200FORcounter=1TO24'Rotateleft-about1/4turnPULSOUT13,650PULSOUT12,650PAUSE20NEXTPAUSE200FORcounter=1TO24'Rotateright-about1/4turnPULSOUT13,850PULSOUT12,850PAUSE20NEXTPAUSE200FORcounter=1TO64'BackwardPULSOUT13,650PULSOUT12,850PAUSE20NEXTEND该你了使机器人绕一个轮子旋转。二、调整基本运动

设想正写一个程序使机器人全速向前运动十五秒钟。如果当机器人应该向前直线运动时有轻微的向左或向右偏移怎么办呢?不需要拆开机器人的后半部分并用螺丝刀重新调整电机。你可以简单地修改程序使Boe-Bot的两个轮子以相同的速度运行。螺丝起子调节叫做“硬件调节”,程序调节叫做“软件调节”。

当Boe-Bot车用该向前走时,一组钩长的距离来检查它是否偏左或偏右,可以简单的修改程序使Boe-Bot的两个轮子以相同的速度运行,程序示例,观察在向前走的10秒钟Boe-Bot是否偏移。表3-1PULSOUTDuration组合P13P12描述运动状况850650全速,P13电机逆时针,P12电机顺时针

650850850850650650750850650750750750两个电机都静止,因为在第四节所做的中心点调整760740770730850700800650该你了

调整电机的速度使Boe-Bot的运动轨迹是一条直线。Duration越接近750,点击旋转越慢,如果Boe-Bot轻微左偏,要么左轮太慢,要么右轮太快,但因为Boe-Bot为全速行驶,因此可减小右轮速度,即使右轮的Duration接近750,要使Boe-Bot走直线必须作多次尝试。更改程序,使Boe-Bot车向后走10秒钟,重复直线运动的测试。

我们可以通过调节Boe-Bot车旋转期望的角度,用FOR….NEXT循环控制旋转角度。这是程序ForwardLeftRightBackward.bs2的向左旋转子程序。FORcounter=1TO24'Rotateleft-about1/4turnPULSOUT13,650PULSOUT12,750PAUSE20NEXT

比如说Boe-Bot转动90°多一点的情况。试试FORcounter=1TO23,或者用偶数个循环FORcounter=1TO22。如果旋转的角度不够,可以增加FOR…NEXT循环的EndValue参数值来增加旋转四分之一周所需的时间如果发现一个值使旋转超过90°,而另一个使旋转小于90°,尝试选择一个使其旋转更多的值,然后稍微减小电机速度。在向左旋转的情况下,两个PULSOUT命令的Duration参数值都要从650改到接近750。在直线运动中,这也是一个迭代法。该你了——90°旋转

更改程序ForwardLeftRightBackward.bs2使其做精确的90°旋转。

三、计算运动距离我们知道:时间=距离/速度,可以用机器人做同样的练习,只要掌握了距离是多少,则

但这里必须要测试Boe-Bot车的速度,我们把Boe-Bot车放在尺子旁边,让Boe-Bot车向前走1秒钟,测试Boe-Bot车走了多远,得到它的速度。输入、保存并运行程序ForwardOneSecond.bs2。'RoboticswiththeBoe-Bot-ForwardOneSecond.bs2'MaketheBoe-Botrollforwardforonesecond.'{$STAMPBS2}'{$PBASIC2.5}DEBUG"ProgramRunning!"counterVARWordFREQOUT4,2000,3000'Signalprogramstart/reset.FORcounter=1TO41PULSOUT13,850PULSOUT12,650PAUSE20NEXTEND

在前面的学习中,我们认识到在一个FOR…NEXT循环中,每次执行两个电机的PULSOUT命令和一个PAUSE命令需要24.6ms(0.024s)的时间。此数的倒数就是每秒钟传递给每个电机的脉冲数。倒数即是交换一个分数的分子和分母。取得倒数的另一个方法是用1除这个数,换句话说,(1/0.024)s/pulse=40.65pulses/s.因为你知道Boe-Bot车向前移动的时间(2.22s)和BASICStamp每秒发给伺服电机的脉冲数(40.65pulses/s),就可以用这些数来计算发给电机的脉冲数。这个数就是FOR…NEXT循环中的EndValue参数值

'RoboticswiththeBoe-Bot-ForwardOneSecond.bs2例――51厘米所需的时间例――20英寸所需的时间以9英寸/秒的速度,你的Boe-Bot车以23cm/s的速度,你的Boe-Bot必须必须用2.22s才能走20英寸运行2.22s才能运行51cm。.

四匀变速运动

匀变速是渐渐增加或减小电机速度的一种方式,而不是骤起或骤停。这种方法可以增加Boe-Bot机器人的电池和电机的寿命。编写匀变速运动的程序匀变速运动的关键是给PULSOUT命令的Duration参数赋予变量。图4-4显示的是一个FOR…NEXT循环它能使Boe-Bot机器人的速度由停止到全速。FOR…NEXT循环每重复执行一次,pulseCount变量就增加1。第一次循环后,pulseCount变量的值是1,就像是在执行命令PULSOUT13,751和PULSOUT12,749。第二次循环后,pulseCount变量的值是2,象在执行命令PULSOUT13,752和PULSOUT12,748。随着pulseCount变量值的增,电机的速度也在逐渐增加。到循环执行100次后,pulseCount变量的值是100,就象在行电机全速运转的命令PULSOUT13,850和PULSOUT12,650回顾第二章任务5,FOR…NEXT循环也可以由高向低记数。你可以通过使用FORpulseCount=100TO1来实现速度的逐渐减小。这是一个使用FOR…NEXT循环来实现速度逐渐增加到全速然后减小的例子。示例程序:StartAndStopWithRamping.bs2

'---[Title]----------------------------------------------------'RoboticswiththeBoe-Bot-StartAndStopWithRamping.bs2'Rampup,goforward,rampdown.'{$STAMPBS2}'{$PBASIC2.5}DEBUG"ProgramRunning!"pulseCountVARWord'FOR...NEXTloopcounter.'---[Initialization]------------------------------------------FREQOUT4,2000,3000'Signalprogramstart/reset.'-----[MainRoutine]--------------------------------------------'Rampupforward.FORpulseCount=1TO100'Looprampsupfor100pulses.

PULSOUT13,750+pulseCount'Pulse=1.5ms+pulseCount.PULSOUT12,750–pulseCount'Pulse=1.5ms–pulseCount.PAUSE20'Pausefor20ms.NEXT'Continueforwardfor75pulses.FORpulseCount=1TO75'Loopsends75forward.pulses.PULSOUT13,850'1.7mspulsetoleftservoPULSOUT12,650'1.3mspulsetorightservo.PAUSE20'Pausefor20ms.NEXT'Rampdownfromgoingforwardtoafullstop.FORpulseCount=100TO1'Looprampsdownfor100pulses.PULSOUT13,750+pulseCount'Pulse=1.5ms+pulseCount.PULSOUT12,750-pulseCount'Pulse=1.5ms-pulseCount.PAUSE20'Pausefor20msNEXTEND'Stopuntilreset该你了

创建一个程序,将加速或减速与其他的动作结合起来。下面是一个逐渐增加速度后走而不是向前走的例子。加速向后走与向前走的唯一不同之处在于PULSOUT13命令中pulseCount的值由750逐渐减小,而向前走是逐渐增加的,相应的,PULSOUT12命令中pulseCount的值由750减少改为逐步增加。

RampuptofullspeedgoingbackwardsFORpulseCount=1TO100PULSOUT13,750-pulseCountPULSOUT12,750+pulseCountPAUSENEXT

通过增加两个PULSOUT命令中pulseCount的值到750来创建一个在旋转中匀变速的程序。通过逐渐减小两个PULSOUT命令中pulseCount的值,可以沿另一个方向匀变速旋转。这是一个匀变速旋转四分之一周的例子。在伺服电机不得不减速之前没机会增加到全速。

FORpulseCount=0TO30PULSOUT13,750+pulseCountPULSOUT12,750+pulseCountPAUSE20NEXT'RampdownrightrotateFORpulseCount=30TO0PULSOUT13,750+pulseCountPULSOUT12,750+pulseCountPAUSE20NEXT从任务1中打开程序ForwardLeftRightBackward.bs2,存为ForwardLeftRightBack更改新的程序,使Boe-Bot机器人的每一个动作能够匀加速和匀减速。提示:你可以使用上面的代码片段和StartAndStopWithRamping.bs2程序中相似的片段。五、用子程序简化导航

1、子程序一个PBASIC子程序有两个部分。一部分是子程序调用,它告诉程序跳到可重复执行代码部分,执行后回到调用点。另一部分是实际的子程序,它以作为自己的名字的标号为子程序的起点,以RETURN命令结束。这个标号和RETURN命令之间的命令组成一个代码段,执行你想让子程序做的工作。

上图是包括一个子程序调用和一个子程序的PBASIC程序的一部分。子程序调用是GOSUBMy_Subroutine命令。实际的子程序是从标号My_Subroutine到RETURN命令之间的部分。它是这样工作的:当程序运行到GOSUBMy_Subroutine命令时,它会寻找标号My_Subroutine:,如箭头(1)所示,程序跳到My_Subroutine处并开始执行命令。程序从标号处向下逐行执行命令,在调试终端你会看到“Commandinsubroutine”信息。PAUSE1000会使程序中断一秒钟,然后程序执行到RETURN命令处,箭头(2)显示了GOSUB命令执行后如何立即跳回。在这种情况下,DEBUG命令显示信息“Aftersubroutine”。程序示例:OneSubroutine.bs2'RoboticswiththeBoe-Bot-OneSubroutine.bs2.'Thisprogramdemonstratesasimplesubroutinecall'{$STAMPBS2}'{$PBASIC2.5}DEBUG"Beforesubroutine",CRPAUSE1000GOSUBMy_Subroutine:DEBUG"Aftersubroutine",CRENDMy_Subroutine:DEBUG"Commandinsubroutine",CRPAUSE1000RETURN

监视调试终端,按几次复位按钮。每一次你应该得到和命令右边相同的三个信息

下面是有两个子程序的例子,一个产生高音另一个产生低音。在DO和LOOP之间的命令依次调用子程序,验证次程序并关注其结果。'RoboticswiththeBoe-Bot-TwoSubroutine.bs2'Thisprogramdnmonstratesthatasubroutineisareusableblockofcommands.'{$STAMPBS2}'{$PBASIC2.5}DOGOSUBHIGH-PitchDEBUG"Backinmain",CRPAUSE1000GOSUBLOW-PitchDEBUG"Backinmainagain",CRPAUSE1000DEBUG"Repeat...",CR,CRLOOPHIGH-Pitch:DEBUG"Highpitch",CRFREQOUT4,2000,3500RETURNLOW-Pitch:DEBUG"Lowpitch",CRFREQOUT4,2000,2000

让我们试着将前,左,右和后四个导航程序放在子程序中,下面是一个例子。示例程序:

MovementsWithSubroutines.bs2'RoboticswiththeBoe-Bot-MoventsWithSubroutines.bs2'Makeforward,left,right,andbackwardmovements.'{$STAMPBS2}'{$PBASIC2.5}DEBUG"ProgramRunning!:"counterVARWordFREQOUT4,2000,3000'Signalprogramstart/reset.GOSUBForwardGOSUBLeftGOSUBRightGOSUBBackwardENDForward:FORcounter=1TO64'ForwardPULSOUT13,850PULSOUT12,650PAUSE20NEXTPAUSE200RETURNLeft:FORcounter=1TO24'Rotateleft-about1/4turnPULSOUT13,650PULSOUT12,650PAUSE20NEXTPAUSE200RETURNRight:FORcounter=1TO24'Rotateright-about1/4turnPULSOUT13,850PULSOUT12,850PAUSE20NEXTPAUSE200RETURNBackward:FORcounter=1TO64'BackwardPULSOUT13,650PULSOUT12,850PAUSE20NEXTRETURN

我们还可以用其他的方法来实现这些动作,如用一个子程序和一些变量来实现。我们可以注意到,目前为止每个机器人动作都用相同的代码块来完成,比较下面两个片段:'Forwardfullspeed'RampdownfromfullspeedbackwardsFORcounter=1TO64FORpulseCount=100TO1PULSOUT13,850PULSOUT13,750-pulseCountPULSOUT12,650PULSOUT12,650+pulseCountPAUSE20PAUSE20NEXTNEXT

使这两个代码块做不同操作的是变量StartValue和EndValue以及PULSOUT的参数Duration的改变。这些变量是可变的,这些变量可以在程序运行的过程中被重复更改来产生不同的动作。下面的程序重复同样的子程序而不是使用带有特定的PULSOUT命令参数Duration的单独的子程序。产生不同动作的关键是在调用子程序前将变量设为适当的值。

程序示例:

'RoboticswiththeBoe-Bot-MoventsWithVariablesAndOneSubroutine.bs2'Makeanavigationroutinethatacceptsparameters.'{$STAMPBS2}'{$PBASIC2.5}DEBUG"ProgramRunning!:"counterVARWordpulseLeftVARWordpulseRightVARWordpulseCountVARWordFREQOUT4,2000,3000'Signalprogramstart/reset.'ForwardpulseLeft=850:pulseRight=650:pulseCount=64:GOSUBNavigate'LeftturnpulseLeft=650:pulseRight=650:pulseCount=24:GOSUBNavigate'RightturnpulseLeft=850:pulseRight=850:pulseCount=24:GOSUBNavigate'BackwardpulseLeft=650:pulseRight=850:pulseCount=64:GOSUBNavigateENDNavigate:FORcounter=1TOpulseCountPULSOUT13,pulseLeftPULSOUT12,pulseRightPAUSE20NEXTPAUSE200RETURN

这个程序中的指令以一种新的方式排列。每个变量声明和GOSUB命令在同一行用冒号分隔开,而不是在不同的行。这里,冒号的功能和回车键一样,分隔开每个PBASIC指令。这种方式允许所有指定动作的新变量值放在一起,并且和子程序调用在同一行。六:在EEPROM中建立复杂动作

EEPROM意为电可擦除可编程只读存储器,BASICStemp中能够容纳2048字节的信息,EEPROM存储器与RAM(随机存取存储器)变量存储器在几个方面不同:1、EEPROM存储一个值要花费更多时间,有时需要几毫秒。2、EEPROM可以接受写操作的次数是一个有限数,大约10百万次,而RAM能无限次的读写。3、EEPROM的主要功能是存储程序,数据可以存在剩余的部分。可以通过单击BASICStamp编辑器中的Run菜单,选择“MemoryMap”来浏览BASICStamp的EEPROM的内容。图4-6显示了程序MovementsWithSubroutines.bs2的存储图。

注意左边的EPROM精简图。底部的小框图的阴影部分显示了程序MovemntsWithSubroutines.bs2占用的内存数量。在这儿,声明成字变量的“counter”变量在RAM图的寄存器0中。这个个程序在输入的时候似乎比较大,但是它只占用了可用的2048字节程序存储区的136个字节。这里还有足够的空间来存放一串相当长的指令。因为在内存中一个字符占用一个字节,因此还有可以存放1912个单字符指令的空间。EEPROM指南到目前为止我们已经试过三种不同的编程方法来使Boe-Bot车向前走,左转,右转和向后走。每种方法都有它的优点,但是如果你要让机器人执行一个更长,更复杂的动作作时用这些方法都很麻烦。下面要介绍的一个例子将在子程序中使用熟悉的代码块来实现每个简单的动作,每个动作都用一个单字母代码来表示,一长串代码字母存储在EEPROM中,然后在程序执行过程中读出并解码。避免了重复执行一长串子程序或者每个GOSUB命令执行前更改变量。这种编程方法需要一些新的PBASIC指令:DATA指令,READ和SELECT...CASE...ENDSELECT命令,在试验示例程序之前,让我们先学习一下这些新的指令。每个基本动作都由一个与子程序相符的单字母代码来代替F代表Forward,B代表Backward,L代表Left_Turn,R代表RightTurn,复杂的Boe-bot运动可以很快的用这些代码设计字母出来。一串字母的最后一个字母是Q,意思是动作完成后退出(Quit)。下载程序时用DATA指令把这个字母串存在EEPROM中。如下所示:DATA"FLFFRBLBBQ"每个字母被存在EEPROM中的一个字节里,由地址0开始(除非我们告诉它在哪里),READ命令能够在程序运行的时候从EEPROM中读出这个字母串。这些值可以这样从DO…LOOP循环中读出:

DOUNTIL(instruction="Q")READaddress,instructionaddress=address+1'PBASICcodeblockomittedhere.LOOPaddress变量是每个存放代码字母的EEPROM字节的地址。Instruction变量拥有字节的实际值,即代码字符。注意每执行一次循环,address变量的值增加1。这就使每个字母从地址0开始从EEPROM字节中连续的读出。DO…LOOP命令有可选的条件,这对于不同的情况是很便利的。DONUTIL(condition)…LOOP允许循环重复执行直到确定的情况发生。DOWHILE(condition)...LOOP允许当某一个条件存在循环重复执行。我们的例子将使用DO…LOOPUNTIL。在这种情况下DO…LOOP循环重复执行直到从EEPROM中读到Q字符。

SELECT...CASE...ENDSELECT指令用来选择一个变量并求值,然后执行CASE列中对应的代码块下面的代码块将根据instruction变量中的字母值调用合适的子程序:SELECTinstructionCASE"F":GOSUBForwardCASE"B":GOSUBBackwardCASE"R":GOSUBRight_TurnCASE"L":GOSUBLeft_TurnENDSELECT程序示例:EepromNavigation.bs2,机器人按矩形行走'RoboticswiththeBoe-Bot-EepromNavigation.bs2'NavigationusingcharactersstoredinEEPROM.'{$STAMPBS2}'{$PBASIC2.5}DEBUG"ProgramRunning!:"'-[Variables]------------------------------------------------------pulseCountVARWord'StoresnumbeiofpulsesaddressVARByte'StoresEEPROMaddress.instructionVARByte'StoresEEPROMinstruction.'--[EEPROMData]----------------------------------------------------'Address:0123456789'Thesetwocommentedlinesshow'/////'EEPROMaddressofeathdatum.DATA"FLFFRBLBBQ"'Navigationinstruction.'----[Initialization]----------------------------------------------FREQOUT4,2000,3000'Signalprogramstart/reset.'-----[MainRoutine]------------------------------------------------DOUNTIL(instruction="Q")READaddress,instruction'Dataataddressininstruction.address=address+1'Add1toaddressfornextread.SELECTinstruction'Calladifferentsubroutine.CASE"F":GOSUBForward'foreachpossiblecharactorCASE"B":GOSUBBackward'thatcanbefetchedfromCASE"L":GOSUBLeft_Turn'EEPROMCASE"R":GOSUBRight_TurnENDSELECTLOOPEND'Stopexecutinguntilreset'---[SubroutineForward]------------------------------------------Forward:'ForwardSubroutineFORpulseCount=1TO64'Send64forwardpulses.PULSOUT13,850'1.7mspulsestoleftservo.PULSOUT12,650'1.3mspulsestorightservo.PAUSE20'Pausefor20ms.NEXTRETURN'ReturntoMainRoutineloop.'-----[Subroutine_Backward]----------------------------------------Backward:'Backwardsubroutine.FORpulseCount=1TO64'Send64backwardpulses.PULSOUT13,650'1.3mspulsestoleftservo.PULSOUT12,850'1.7mspulsestorightservo.PAUSE20'Pausefor20ms.NEXTRETURN'ReturntoMainRoutineloop.'-----[Subroutine_Left_Turn]----------------------------------------Left_Turn:'Left_TurnsubroutineFORpulseCount=1TO24'Send24leftrotatepulses.PULSOUT13,650'1.3mspulsestoleftservo.PULSOUT12,650'1.3mspulsestorightservo.PAUSE20'Pausefor20ms.NEXTRETURN'ReturntoMainRoutineloop.'-----[Subroutine_Right_Turn]----------------------------------------Right_Turn:'Right_TurnsubroutineFORpulseCount=1TO24'Send24rightrotatepulses.PULSOUT13,850'1.7mspulsestoleftservo.PULSOUT12,850'1.7mspulsestorightservo.PAUSE20'Pausefor20ms.NEXTRETURN'ReturntoMainRoutineloop.该你了

程序进行完毕后,在BASICStamp编辑器中单击Run菜单并选择MemoryMap,就可以看到详细的EEPROM图,我们存放的指令将以蓝色高亮显示,显示的数据是十六进制的ASCII码与我们在DATA指令中输入的字符一致。

单击图中左下角的DisplayASCII复选框,它显示的是你使用DATA指令记录的实际字符,不是ASCII码。

这个程序在EEPROM中存储了10个字符。这10个字符被READ命令的address参数访问。address变量声明成一个字节变量,因而可以访问256个地址,包含我们需要的10个地址。如果address被重声明为一个自变量,你理论上可以访问65535个地址。记住如果你的程序越长,EEPROM中可以用来存储数据的地址会越少可以更改现有的数据串为一系列新的方向。你也可以增加另外的DATA指令。这些数据被连续存储.但应注意:DATA指令中最后的字符应该是“Q”.

下一个例看起来很复杂,但是它是一个非常有效的设计Boe-Bot运动的方法。这个例子使用了EEPROM数据存储区,但是没有使用子程序,而是使用单个的用变量代替FOR...NEXT循环的EndValue和PULSOUTDuration的代码块。缺省的,DATA指令在EEPROM中存储字节信息,要存储字长的数据项,可以增加Word修饰符在DATA指令中。每个字长数据项需要占用EEPROM中的两个字节的存储位置,因此每个数据要通过每个数据的另一个地址来访问。当使用多个DATA指令时,最方便的方法是给每个指令加标签。这样,READ命令就可以根据标签得到数据,不用你计算在EEPROM中每串数据开始的地址。看下面的代码片段:'addressOffset02468Pulses_CountDATAWord64,Word24,Word24,Word64,Word0Pulses_LeftDATAWord850,Word650,Word850,Word650Pulses_RightDATAWord650,Word650,Word850,Word850

每个DATA指令以自己的标签开始。Word修饰符在每个用逗号分开得数据项之前。这三个数据串将被依次存储在EEPROM中。我们不用计算出数据项的地址,因为标签和addressOffset变量会自动去做。READ命令用每个标签算出EEPROM中数据串开始的地址,然后增加addressOffset变量的值就知道要移动多少来找到正确的数据项(DataItem)。找到DataItem.后Address将被存储在READ命令的Variable变量中。注意,Word修饰符应该放在存储从EEPROM中取出的值的变量之前。DOREADPulses_Count+addressOffset,WordpulseCountREADPulses_Left+addressOffset,WordpulseLeftREADPulses_Right+addressOffset,WordpulseRightaddressOffset=addressOffset+2'PBASICcodeblockomittedhere.LOOPUNTIL(pulseCount=0)

第一次执行完循环后,addressOffset=0。第一个READ命令将从Pulses_Count标签的第一个地址中得到一个值64,并把它放在pulseCount变量中。第二个READ命令从Pulses_Left标签指定的第一个地址中得到值850,并把它放在pulseLeft变量中。第三个EAD命令从Pulses_Right标签指定的第一个地址得到值650,并把它放在pulseRight变中。注意,这些是上面代码片段第“0”列的三个值,当这些变量值被放在下面的代码块中时,FORcounter=1TOpulseCountFORcounter=1TO64PULSOUT13,pulseLeftPULSOUT13,850PULSOUT12,pulseRightPULSOUT12,650PAUSE20becomesPAUSE20NEXTNEXT然后FOR...NEXT代码执行第二、第三和第四个循环。

程序示例:EepromNavigationWithWordValues.bs2.'RoboticswiththeBoe-Bot-EepromNavigationWithWordValues.bs2'Storelistsofwordvaluesthatdictate.'{$STAMPBS2}'Stampdirective.'{$PBASIC2.5}'PBASICdirective.DEBUG"ProgramRunning!“'--[Variables]-----------------------------------------------counterVARWordpulseCountVARWord'Storesnumberofpulses.addressOffsetVARByte'Storesoffsetfromlabel.instructionVARByte'StoresEEPROMinstruction.pulseRightVARWord'Storesservopulsewidths.pulseLeftVARWord'--[EEPROMData]--------------------------------------------'addressOffset02468Pulses_CountDATAWord64,Word24,Word24,Word64,Word0Pulses_LeftDATAWord850,Word650,Word850,Word650Pulses_RightDATAWord650,Word650,Word850,Word850'–[Initialization]---------------------------------FREQOUT4,2000,3000'Signalprogramstart/reset.'--[MainRoutine]-----------------------------------DOREADPulses_Count+addressOffset,WordpulseCountREADPulses_Left+addressOffset,WordpulseLeftREADPulses_Right+addressOffset,WordpulseRightaddressOffset=addressOffset+2FORcounter=1TOpulseCountPULSOUT13,pulseLeftPULSOUT12,pulseRightPAUSE20NEXTLOOPUNTIL(pulseCount=0)END'Stopexecutinguntilreset.挑战课题!1、用下面的代码代替DATA指示,运行程序,观察Boe-Bot会做些什么。Pulses_CountDATAWord60,Word80,Word100,Word110,Word110,Word100,Word80,Word60,Word0Pulses_LeftDATAWord850,Word800,Word785,Word760,Word750,Word740,Word715,Word700,Word650,Word750Pulses_RightDATAWord650,Word700,Word715,Word740,Word750,Word760,Word785,Word800,Word850,Word7502、写个程序让Boe-Bot能沿着(1)直径为1m的圆形轨迹运行(2)边长为1m的正三角形轨迹行走。(3)走“8”形轨迹。总结这章节介绍了Boe-Bot的许多基本操作:前进、后退、左转、右转、以中心旋转。这些操作是由PULSOUT指令中的Duration参数所控制,而每个动作的时间是由FOR…NEXT循环中的StartValue和Endvalue参数所控制。第二章介绍的是硬件的调整,用螺丝起子来校正Boe-Bot的伺服机。而这章节是注重在软件方面的调整,尤其是当两个伺服马达的转速不等时,必须对PULSOUT指令中的Duration参数进行修改,降低转速较快的伺服马达,如果两轮的转速没有配合好,做了这个修改就可以让Boe-Bot的轨迹从曲线变成直线。至于调整Boe-Bot的旋转角度,则可以从FOR…NEXT循环中的StartValue与EndValue参数着手。为了写程序让Boe-Bot行走事先决定好的距离,可以先用尺测量出Boe-Bot行走一秒的距离,有了这个距离与每秒钟的脉冲数就可以计算出特定距离所需要的脉冲数。Ramping是一种逐渐加速与逐渐减速的方式,这种方式对于伺服马达是较适合的操作,所以建议在Boe-Bot的起始与结束时使用这种操作。逐渐加速的方法是在FOR…NEXT循环中声明一个Counter参数,在PULSOUT指令中的Duration参数从750开始增加与减少。

子程序是一种事先写好程序的方法,可供PBASIC重复使用。使用子程序就不需要为每一个操作都写一个完整的FOR…NEXT循环,因为每个子程序中就会包含一个FOR…NEXT循环,在需要子程序时就以GOSUB呼叫子程序。子程序以标记为开始,以RETURN指令作为结束。在主程序中以GOSUB指令呼叫子程序,当子程序执行完毕后就会执行RETURN指令,下一个被执行的指令就是紧接在GOSUB指令后的程序。BASICStamp的EEPROM储存现在执行的程序,不过你可以利用程序中任何未使用的部分来储存数值,这是储存预存操作程序的好方式。DATA指令可将数值存入EEPROM,预设模式是以byte存入,若在数据前面加上Word,就可使用EEPROM内存中的2个byte储存数值,数值得大小可提升至65535。我们用READ指令来将存入EEPROM的数值读取出来。如果你要使用的是字符变量是Word格式,记得在变数前面加上Word。

SELECT…CASE…ENDSELECT叙使用来选择一个特定的变量,然后开始评估它属于那种情形,之后才执行某种情形下相对应的程序。附加的DO…LOOP循环这个功能相当的方便,可以在很多情况下达到我们的目的;DOUNTIL(情况)…LOOP和DO…LOOPUNTIL(情况)允许循环不断重复,直到某种条件发生才跳出循环。第二节Boe-Bot机器人触觉导航

本章中,我们将在Boe-Bot车上安装并测试一个称为胡须的触觉开关。并对Boe-Bot机器人编程来监视触觉开关的状态,以及决定当它遇到障碍物时如何去做。最终的结果就是通过触觉给机器人自动导航——即触觉导航。胡须:是因为这些缓冲开关看起来象胡须,也象触角。安装好的胡须如图5-1所示。胡须让机器人有能力通过接触来判断周边的环境,很象蚂蚁的触角,或是猫的胡须。一、安装并测试机器人的胡须1、胡须的电路及装配断开主板和电机的电源,元件清单:须状金属丝、平头M4-40螺丝钉、½″圆形套管、3-pin公-公接头、220Ω电阻(红-红-棕)、10kΩ电阻(棕-黑-橙)。安装步骤:(1)拆掉连接主板到前面支架的两颗螺钉;(2)参考图5-3,螺钉依次穿过尼龙垫圈、螺钉穿过主板上的圆孔之后,拧进主板下面的支架中,但不要拧紧;(3)把须状金属丝带勾的部分拧在螺钉上,将螺钉拧紧在支架上,调整胡须的位置使它们横向交叉但不接触。。电路:把图所示的胡须电路添加到压电式扬声器和你曾在前面学习中搭建并测试过的伺服电机电路中,确定两条胡须比较靠近,但又不接触面包板上的3-pin头。推荐保持3mm的距离。2、测试胡须

观察胡须电路示意图,每条胡须都是一个机械式的、接地常开的单刀单掷开关。胡须接地(Vss)是因为主板外围的镀金孔都连接到Vss。金属支架和螺丝钉提供电气连接给胡须。通过编程让BASICStamp微控制器探测什么时候胡须被触动。连接到每个开关电路的I/O脚监视着10K上拉电阻上的电压变化。图5-8说明是如何工作的。当胡须没有被触动,连接胡须的I/O管脚的电压是5V;当胡须被触动时,I/O短接到地,所以I/O管脚的电压是0V。PBASIC程序开始运行时,所有的I/O插脚缺省为输入。也就是说,连接到胡须的I/O管脚会自动作为输入。作为输入,如果I/O脚上的电压为5V(胡须没有被触动),则其寄存器存储1;如果电压为0V(胡须被触动),则存储0。调试终端可以显示这些数值。

接下来的示例程序是用来测试胡须的功能是否正常。通过显示存储在P7和P5的输入寄存器(IN7和IN5)中的二进制数字,程序将告诉你BASICStamp是否检测到胡须的状态。当输入寄存器存储的值为1,说明胡须没有被触动;当存储值为0时,胡须被触动。程序示例:TestWhiskers.bs2

'RoboticswiththeBoe-Bot-TestWhiskers.bs2'DisplaywhattheI/Opinsconnectedtothewhiskerssense.'{$STAMPBS2}'Stampdirective.'{$PBASIC2.5}'PBASICdirective.DEBUG"WHISKERSTATES",CR,"LeftRight",CR,"------------"DODEBUGCRSRXY,0,3,"P5=",BIN1IN5,"P7=",BIN1IN7PAUSE50LOOP注意调试终端的显示值;此时P7和P5的显示值应该都为1。检查图5-5,弄清哪条胡须是左胡须,哪条是右胡须。(1)把右胡须按到3-pin转接头上,注意调试终端的数值,数值应该为:P5=1P7=0(2)把左胡须按到3-pin转接头上,注意调试终端的数值,数值应该为:P5=0P7=1(3)同时把两个胡须按到各自的3-pin转接头上,此时数值应该为:P5=0P7=0(4)如果两个胡须都通过测试,你可以继续下面的内容;否则检查程序或电路中存在的错误。

3、实地测试胡须假设你以后不得不脱机测试胡须。不能用到调试终端,我们可以对BASICStamp编程,让它发送一些和其接收到的输入信号相符合的输出信号。利用含有一对LED的电路和基于胡须的输入让LED亮或灭的程序来实现。所需元件:220Ω电阻(红-红-棕)、红色LED(1)搭建LED胡须测试电路断开电源,按图示搭建电路(2)对LED胡须测试电路编程

重新连接主板的电源,将程序TestWhiskers.bs2另存为TestWhiskersWithLeds.bs2在PAUSE50和LOOP命令之间插入以下两段IF...THEN语句IF(IN7=0)THENHIGH1ELSELOW1ENDIFIF(IN5=0)THENHIGH10ELSELOW10ENDIF这是IF...THEN条件判断语句。第一个IF...THEN语句当连接到P7的胡须被触动(IN7=0)时,设置P1为高电平LED亮,ELSE部分当胡须没有被触动时,设置P1为低电平LED灭。第二个IF...THEN语句对连接到P5的胡须和P10的LED做同样的事情。运行程序TestWhiskersWithLeds.bs2轻轻的触动胡须,测试该程序。每个胡须接触到自己的3-pin转接头时,红色LED会变亮。'RoboticswiththeBoe-Bot-TestWhiskersWithLeds.bs2'DisplaywhattheI/Opinsconnectedtothewhiskerssense.'{$STAMPBS2}'{$PBASIC2.5}DEBUG"WHISKERSTATES",CRDEBUG"LeftRight",CRDEBUG"-------------"DODEBUGCRSRXY,0,3,"P5=",BIN1IN5"P7=",BIN1IN7PAUSE50IF(IN7=0)THENHIGH1ELSELOW1ENDIFIF(IN5=0)THENHIGH10ELSELOW10ENDIFLOOP二、通过胡须导航在Boe-Bot车行走过程中,如果有胡须被触动,那就意味着碰到了什么。导航程序需要接受这些输入信息,判断它的意义,调用一系列使Boe-Bot车倒退、旋转并朝不同的方向行走的动作子程序,完成胡须导航。PBASIC语言中有个条件判断命令语句IF…THEN,其句法是:IF(condition)THEN…{ELSEIF(condition)}…{ELSE}…ENDIF句中“…”的意思是,你可以在关键词之间放置一个代码段(由一条或多条命令组成)。下面的示例程序会基于胡须的输入做出选择,然后调用相关子程序使Boe-Bot车采取行动。子程序同你在第四章里用到的类似。这是IF…THEN怎样使用:IF(IN5=0)AND(IN7=0)THENGOSUBBack_Up'Bothwhiskersdetectobstacle,GOSUBTurn_Left'backup&U-turn(lefttwice)GOSUBTurn_LeftELSEIF(IN5=0)THEN'LeftwhiskercontactsGOSUBBack_Up'Backup&turnrightGOSUBTurn_RightELSEIF(IN7=0)THEN'RightwhiskercontactsGOSUBBack_Up'Backup&turnleftGOSUBTurn_LeftELSE'Bothwhiskers1,nocontactsGOSUBForward_Pulse'Applyaforwardpulse&ENDIF'checkagain示例程序:RoamingWithWhiskers.bs2这个示例程序示范了一种利用IF…THEN语句评估胡须的输入并决定调用哪个导航子程序的方法。重新打开主板和伺服电机的电源输入、保存并运行程序RoamingWithWhiskers.bs2尝试让Boe-Bot车行走,当在其路线上遇到障碍物时,它将后退、旋转并向另一个方向行走。

'-----[Title]--------------------------------------------------------------'RoboticswiththeBoe-Bot-RoamingWithWhiskers.bs2'Boe-Botuseswhiskerstodetectobjects,andnavigatesaroundthem.'{$STAMPBS2}'Stampdirective.'{$PBASIC2.5}'PBASICdirective.DEBUG"ProgramRunning!“'-----[Variables]----------------------------------------------------------pulseCountVARByte'FOR...NEXTloopcounter.'-----[Initialization]-----------------------------------------------------FREQOUT4,2000,3000'Signalprogramstart/reset.'-----[MainRoutine]-------------------------------------------------------DOIF(IN5=0)AND(IN7=0)THEN'BothwhiskersdetectobstacleGOSUBBack_Up'Backup&U-turn(lefttwice)GOSUBTurn_LeftGOSUBTurn_LeftELSEIF(IN5=0)THEN'LeftwhiskercontactsGOSUBBack_Up'Backup&turnrightGOSUBTurn_RightELSEIF(IN7=0)THEN'RightwhiskercontactsGOSUBBack_Up'Backup&turnleftGOSUBTurn_LeftELSE'Bothwhiskers1,nocontactsGOSUBForward_Pulse'ApplyaforwardpulseENDIF'andcheckagainLOOP'-----[Subroutines]--------------------------------------------------------Forward_Pulse:'Sendasingleforwardpulse.PUL

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论