Файл: Advanced Robotics with the Toddler (Paralax, student guide, v1.3, 2004).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 12.06.2025

Просмотров: 1934

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Chapter #7: Staying on the Table · Page 157

OUTPUT right_pin

FREQOUT 2,500,3000

' Beep at startup.

GOSUB ResetCC

'----- Main Routine --------------

main:

' Main routine

GOSUB check_sensors

' Distance values for each sensor

'debug "l",dec l_values,"r", dec r_values,cr

BRANCH l_values,[left0,left1,left2,left3,left4,left5]

left0:

LOOKUP r_values,[l0r0,l0r1,l0r2,l0r3,l0r4,l0r5],Mx GOTO main_movement

left1:

LOOKUP r_values,[l1r0,l1r1,l1r2,l1r3,l1r4,l1r5],Mx GOTO main_movement

left2:

LOOKUP r_values,[l2r0,l2r1,l2r2,l2r3,l2r4,l2r5],Mx GOTO main_movement

left3:

LOOKUP r_values,[l3r0,l3r1,l3r2,l3r3,l3r4,l3r5],Mx GOTO main_movement

left4:

LOOKUP r_values,[l4r0,l4r1,l4r2,l4r3,l4r4,l4r5],Mx GOTO main_movement

left5:

LOOKUP r_values,[l5r0,l5r1,l5r2,l5r3,l5r4,l5r5],Mx

main_movement:

GOSUB Movement

GOTO main

' Infinite loop.

'----- Subroutine(s) -------------

check_sensors:

l_values

= 0

' Set distances to 0.

r_values

= 0

' Take 5

measurements for distance at each IR pair. If you fine tuned

Page 158 · Advanced Robotics with the Toddler

' frequencies in Activity #2, insert them in the lookup tables.

FOR counter = 0 TO 4 check_left_sensors:

LOOKUP counter,[37500,38250,39500,40500,41000],l_IR_freq FREQOUT left_pin,1,l_IR_freq

l_values.LOWBIT(counter) = ~left_in

check_right_sensors:

LOOKUP counter,[37500,38250,39500,40500,41000],r_IR_freq FREQOUT right_pin,1,r_IR_freq

r_values.LOWBIT(counter) = ~right_in

NEXT

l_values = NCD l_values

' Value for distance depends on MSB

r_values = NCD r_values

RETURN

'----- Movement: Move feet using DATA table referenced by Mx -----

'Input: Mx = movement table index, table ends in xx

'or

'Mx = submovement table index, table ends in xx

'

' Note: All submovment tables come after the movment tables in this file.

Movement:

IF Mx < BasicMovements THEN SetupMovement

MxCurrent = Mx

' setup to use submovement table

MoveLoopLimit = 1

GOTO StartMovement

SetupMovement:

READ Mx, MoveLoopLimit

' read movement table repeat count

MxCurrent = Mx +

1

StartMovement:

FOR MoveLoop = 1

TO MoveLoopLimit

Mx = MxCurrent

' Mx = start of movement table

'debug hex Mx, " Movement ", dec MoveLoop, " of ", dec MoveLoopLimit,cr

IF Mx < BasicMovements THEN MovementLoop

' skip if movement table

SxCurrent = Mx

'

SxCurrent = submovement index

GOTO StartSubMovement

'

enter middle of loop

MovementLoop:


Chapter #7: Staying on the Table · Page 159

READ Mx, SxCurrent

'

read next submovment byte

Mx = Mx + 1

IF SxCurrent = xx THEN MovementDone

'

skip if end of list

'debug

" ", hex SxCurrent, " movement",cr

LOOKUP SxCurrent,[Finish,Forward,Backward,LeftTurn,RightTurn,

PivotLeft,PivotRight],SxCurrent

'

lookup submovement table index

StartSubMovement:

'

start executing submovement table

READ SxCurrent, SubMoveLoopLmt

'

read submovement table repeat count

SxCurrent = SxCurrent + 1

FOR

SubMoveLoop = 1 TO SubMoveLoopLmt

Sx = SxCurrent

'debug

"

", hex Sx, " submovement ",

dec SubMoveLoop, " of "

'debug

dec SubMoveLoopLmt,cr

SubMovementLoop:

READ Sx, Dx

'

read next submovent action

Sx = Sx + 1

IF Dx = xx THEN SubMovementDone

'

skip if end of list

GOSUB DoMovement

'

execute movement

GOTO SubMovementLoop

SubMovementDone: NEXT

IF Mx < BasicMovements THEN MovementLoop

' exit if submovement table

MovementDone: NEXT

RETURN

DoMovement:

'debug " ", dec Dx, " action",cr

BRANCH Dx,[TiltLeft,TiltCenter,TiltRight,StrideLeft, StrideCenter,StrideRight]

' will fall through if invalid index

RETURN

' ---- Movement routines can be called directly ----

TiltLeft:

NewValue = LeftTilt

GOTO MovementTilt

TiltCenter:

NewValue = CenterTilt

GOTO MovementTilt


Page 160 · Advanced Robotics with the Toddler

TiltRight:

NewValue = RightTilt

MovementTilt:

FOR Pulses = CurrentTilt TO NewValue STEP TiltStep

PULSOUT TiltServo, Pulses

PULSOUT StrideServo, CurrentStride

PAUSE MoveDelay

NEXT

CurrentTilt = NewValue

RETURN

StrideLeft:

NewValue = LeftStride

GOTO MovementStride

StrideCenter:

NewValue = CenterStride

GOTO MovementStride

StrideRight:

NewValue = RightStride

MovementStride:

FOR Pulses = CurrentStride TO NewValue STEP StrideStep

PULSOUT TiltServo, CurrentTilt

PULSOUT StrideServo, Pulses

PAUSE MoveDelay

NEXT

CurrentStride = NewValue

RETURN

' ----- Move feet to initial center position -----

ResetCC:

CurrentTilt = CenterTilt

CurrentStride = CenterStride

FOR Pulses = 1 TO 100 STEP StrideStep

PULSOUT TiltServo, CenterTilt

PULSOUT StrideServo, CenterStride

PAUSE MoveDelay

NEXT

DoReturn:

RETURN

Chapter #7: Staying on the Table · Page 161

How the Shadow Walker Program Works

The first thing the main routine does is call the check_sensors subroutine. After the check_sensors subroutine is finished, l_values and r_values each contain a number corresponding to the zone in which an object was detected for both the left and right IR pairs.

main:

GOSUB check_sensors

The next line of code jumps to one of many LOOKUP statements. The BRANCH statement uses the status of the left IR sensor while the LOOKUP statements use the status of the right IR sensor. These set the Mx variable with the table index for the movement to be performed by the Movement routine.

Branch l_values,[left0,left1,left2,left3,left4,left5]

left0:

LOOKUP r_values,[l0r0,l0r1,l0r2,l0r3,l0r4,l0r5],Mx GOTO main_movement

left1:

LOOKUP r_values,[l1r0,l1r1,l1r2,l1r3,l1r4,l1r5],Mx GOTO main_movement

left2:

LOOKUP r_values,[l2r0,l2r1,l2r2,l2r3,l2r4,l2r5],Mx GOTO main_movement

left3:

LOOKUP r_values,[l3r0,l3r1,l3r2,l3r3,l3r4,l3r5],Mx GOTO main_movement

left4:

LOOKUP r_values,[l4r0,l4r1,l4r2,l4r3,l4r4,l4r5],Mx GOTO main_movement

left5:

LOOKUP r_values,[l5r0,l5r1,l5r2,l5r3,l5r4,l5r5],Mx

main_movement: GOSUB Movement

The values used in the LOOKUP statement are defined near the start of the program using CON constant definitions. While it is possible to put these values in the LOOKUP statement,

Page 162 · Advanced Robotics with the Toddler

this makes the statements long. It also makes it difficult to see what action is performed in a particular state. The constant definitions provide a way to do this. It is now easy to correlate a particular state such as l3r3 with a particular movement, in this case a nop or no movement. Likewise, l5r5 indicates that the Toddler is immediately in front of an obstacle and l0r0 indicates the Toddler has not located an obstacle within its range.

Program control is returned to the main: label after the movement has been performed, and the loop repeats itself.


Chapter #7: Staying on the Table · Page 163

CHALLENGES

Figure 7-5: One Toddler Follows Another Toddler

Figure 7.5 shows a lead Toddler followed by a shadow Toddler. The lead Toddler could run any of the prior programs provided the speed is slower (increase the PAUSE values or decrease the STEP values) and the shadow Toddler is running Program Listing 7.3: Shadow Walker. Proportional control makes the shadow Toddler a very faithful follower. One lead Toddler can string along a chain of 2 or 3 Toddlers. Just add a 4” x 4” paper to the lead Toddler’s backside.

If you are part of a class, mount paper panel on the back of the lead Toddler as shown in Figure 7.5.

If you are not part of a class (and only have one Toddler) the shadow Toddler will follow a piece of paper or your hand just as well as it follows a lead Toddler.

Page 164 · Advanced Robotics with the Toddler

The Shadow Toddler should be running Program Listing 7.3 without any modifications.

With both Toddlers running their respective programs, place the shadow Toddler behind the lead Toddler. The shadow Toddler follows at a fixed distance, so long as it is not distracted by another object such as a hand or a nearby wall.

Chapter #8: Real-Time Programming with Bumpers and Infrared · Page 165

Chapter #8: Real-Time Programming with Bumpers and Infrared

Note to reader: This chapter requires the Toddler Toes Kit (#27312) from Parallax.

WHAT IS MEANT BY REAL TIME?

Real time programming is one of those terms that can mean different things at the same time. In plain language, it is code that allows the computer system to keep up with what is happening in the world around it – WHILE it is happening. Like in everything else, there are degrees of “real time”. Programming a system to respond to events happening quickly is more difficult than if they happen more slowly. Programming events to happen at a very precise time can also be challenging – even if they don’t happen at high speed.

Let’s look at a simple example.

You want to flash 5 LEDs. You can determine if they need to be on or off by testing switch inputs. It’s an easy task.

1.Turn off all the LEDs to start

2.Test each switch input and turn on the LED if the switch requires it.

3.Pause for ½ second – or however long you want the LEDs on.

4.Turn off all the LEDs

5.Pause for ½ second – or however long you want the LEDs off.

6.Go to to #2 and start over.

You probably ignored how long it takes to test the inputs in step #2 before running the PAUSE in step #3. What if the program were required to flash the LEDs at precisely a 1 second rate (+- 0.001%)? Ignoring the calculation times can lead to disaster in that case. Not only would you have to measure or calculate the instruction times to correct the duration of the PAUSE but also you’d have to make sure that all possible cases of switch inputs take the same amount of time to compute.

Now, what if the switches only make contact for 20 milliseconds? Your code would have to constantly be scanning to see if the switch was making contact and remember it. The scanning has to happen while still keeping track of the flashing LEDs. If you had a loop to check the switches, you’d have to complete that loop more than once every 20