'Thor_8-1.bas 40x2 Firmware v3 'Thor_7-1.bas 40x2 Firmware v3 #picaxe 40x2 #slot 1 #no_table #no_data #define keybip 'for GetCmnd DISCONNECT SETFREQ m16 'SERTXD 19200 @m16 'HSERSETUP B19200_16,%00101 'pulsout 4MHz 10us units 'pulsout 16MHz 2.5us units '#1 Memory used = 3798 bytes out of 4096 '----------------------------------------- 'BUGS '---- 'Hlt: 'stand with right foot forward ' GOSUB SLR 'is this needed? 'NewBehave: ' TT =TTcmnd -"1" *2 +18 '1,18 2,20 3,22 4,24 5,26 6,28 7,30 8,32 'is this right?Freya? '************************* Machine Dependent ***************************** 'Notes '----- 'hips Supertec S03, ankles Supertec S03 'SERVOS LEFT RIGHT 'Hips S3 [FootUp=- FootDown=+] S1 [FootUp=+ FootDown=-] 'Ankles S2 [ToeFd=- ToeBk=+ ] S0 [ToeBk=- ToeFd=+ ] 'Ankles ie S2 [ToeLeft=- ToeRight=+] S0 [ToeLeft=- ToeRight=+] ' 'LOGICAL 'Hips S3 [FootUp=- FootDown=+] S1 [FootUp=+ FootDown=-] 'Ankles S2 [ToeFd=+ ToeBk=- ] S0 [ToeBk=- ToeFd=+ ] ' 'Allp logical values ' 'max speed ~12, works at 15 but feet start to catch on each other. '************************* END Machine Dependent ************************* '================================================== Pins: '================================================== SYMBOL servoLA =A.1 SYMBOL servoLH =A.0 SYMBOL servoRA =D.3 SYMBOL servoRH =D.2 SYMBOL whiskerLLED =A.6 SYMBOL whiskerRLED =A.7 SYMBOL whiskerL =A.5 'READADC needs port.pin not a symbol SYMBOL whiskerR =D.0 'READADC needs port.pin not a symbol SYMBOL EyeLLED =C.1 SYMBOL EyeRLED =C.2 SYMBOL feelerLLED =D.7 SYMBOL Lfeeler =pinD.6 'READADC needs port.pin not a symbol SYMBOL Rfeeler =pinD.5 'READADC needs port.pin not a symbol SYMBOL feelerRLED =D.4 SYMBOL pingpin =C.0 SYMBOL voiceLED =C.5 SYMBOL voice =C.5 SYMBOL senseLtoe =pinA.2 SYMBOL senseRtoe =pinD.1 SYMBOL inIR =A.3 SYMBOL inIRpin =pinA.3 'SYMBOL O_LCD =A.4 'bus B.7 - B.0 '================================================== 'Reactions Table: in #0 SYMBOL USaware =0 'TABLE USaware, ("vttatmtm.") SYMBOL USnear =16 'TABLE USnear, ("vss-Btatmtm.") SYMBOL OLR =32 'TABLE OLR, ("s-BBtatmtm.") SYMBOL OL_ =48 'TABLE OL_, ("s-BRR.") '2023-01-03 SYMBOL O_R =64 'TABLE O_R, ("s-BLL.") '2023-01-03 SYMBOL HLR =80 'TABLE HLR, ("s-BBBBtatmtm.") '2023-01-03 SYMBOL HL_ =96 'TABLE HL_, ("s-BRRR.") '2023-01-03 SYMBOL H_R =112 'TABLE H_R, ("s-BLLL.") '2023-01-03 SYMBOL ReactEnd =127 'TABLE ReactEnd,(".") '================================================== VarsCons: '========================== SYMBOL mindstart =128 'table in #0 SYMBOL Esc =27 'Escape key SYMBOL quote2 =34 'double quote mark 'built in variables 'bptr = RAM pointer 'ptr - scratchpad pointer 'hserptr - pointer to scratchpad location of last byte received by hardware UART 'X2 parts - bit0-31 b0-55 w0-27 +56 - 255 Peek/Poke 'W0 SYMBOL sense0 =b0 SYMBOL temp0 =b0 SYMBOL f8_behaves =b1 'used in programs 0123 w=write r=read !=wr SYMBOL f_b_react =bit8 'wrr- 1=reacts on SYMBOL f_b_autosense =bit9 'w!r- 1= auto test sensors, "b$a" 'SYMBOL f_b_autoUp =bit10 'wrr- tested in Qfell, default=1 "bu" Baldur SYMBOL f_b_Uon =bit11 'w!R- Ultrasonic sense ON SYMBOL f_b_F =bit12 '-!-- Forward - set by Fd/Bk etc SYMBOL f_Bmodified =bit13 'w!-- behaviour settings modified 'SYMBOL f_tF =bit14 '-!-- last turn on spot Baldur SYMBOL f_MoveAborted =bit15 '-!-- 'W1 SYMBOL f8_Cmnder0 =b2 SYMBOL f_warm =bit16 '!--- SYMBOL f_play =bit17 '!--- SYMBOL f_record =bit18 '!--- SYMBOL f_recordC =bit19 '!--- SYMBOL f_waitcmnd =bit20 '!--- just wait for an IRkey or Serin SYMBOL f_IRcmnd =bit21 '!r-- 1=>IRcmnd 0=>Serial/Play cmnd SYMBOL f_page0 =bit22 'w-!- 1=Acts/Slots 01-07, 0(default) =1-8 SYMBOL f_Rfwd =bit23 'w!-- SYMBOL f8_doServos =b3 'ww-- SYMBOL f_RAdo =bit24 '-!-! do servo SYMBOL f_RHdo =bit25 '-!-! do servo SYMBOL f_LAdo =bit26 '-!-! do servo SYMBOL f_LHdo =bit27 '-!-! do servo SYMBOL f_RApulse =bit28 'r!-r pulse servos SYMBOL f_RHpulse =bit29 'r!-r pulse servos SYMBOL f_LApulse =bit30 'r!-r pulse servos SYMBOL f_LHpulse =bit31 'r!-r pulse servos 'W2 SYMBOL W2pulse =w2 SYMBOL W2pulselo =b4 SYMBOL W2pulsehi =b5 SYMBOL W2temp =w2 'Interpage jumps for hserptr SYMBOL W2templo =b4 SYMBOL W2temphi =b5 SYMBOL W2temp0 =b4 SYMBOL W2temp1 =b5 'W3 SYMBOL cmnd =b6 SYMBOL RootCmnd =b7 SYMBOL servonum =b7 'SETUP 'W4 SYMBOL RHC =b8 'Right Hip Centre for current posture SYMBOL LHC =b9 'Left Hip Centre for current posture 'W5 SYMBOL RAC =b10 'Right Ankle Centre for current posture SYMBOL LAC =b11 'Left Ankle Centre for current posture 'W6 SYMBOL RHat =b12 'Servo Right Hip At SYMBOL RHto =b13 'Servo Right Hip To 'W7 SYMBOL LHat =b14 'Servo Left Hip At SYMBOL LHto =b15 'Servo Left Hip To 'W8 SYMBOL RAat =b16 'Servo Right Ankle At SYMBOL RAto =b17 'Servo Right Ankle To 'W9 SYMBOL LAat =b18 'Servo Left Ankle At SYMBOL LAto =b19 'Servo Left Ankle To 'W10 SYMBOL Sspeed =b20 '1-9 SYMBOL Sframe =b21 'Servo frame pause in ms 'W11 SYMBOL FL =b22 'Foot Lift UpDown movement min 25 SYMBOL FP =b23 'Foot Pace ForwardBack movement +- 9 - 23 'W12 SYMBOL FT =b24 'Foot Turn SYMBOL FLcmnd =b25 'Foot Lift UpDown movement 0-9 'W13 SYMBOL FPcmnd =b26 'Foot Pace ForwardBack movement 0-9 SYMBOL FTcmnd =b27 'Foot Turn movement 0-9 'W14 SYMBOL Scmnd =b28 'Speed 1-9 SYMBOL IRcmnd =b29 'W15 SYMBOL Actptr =b30 SYMBOL ActEnd =b31 'W16 SYMBOL slot =b32 SYMBOL hframes =b33 'halt frames 'W17 SYMBOL kickcmnd =b34 ' SYMBOL Speedmax =b35 '1-9 'W18 'SYMBOL FUScmnd =b36 'Foot Up In = 9 -FUI *FL /9 Baldur SYMBOL ReactAt =b37 'React Table pointer 'W19 SYMBOL yawn =b38 SYMBOL standOnLR =b39 '%LR 1=down moving test toes if if <>%11 'W20 SYMBOL topple =b40 SYMBOL usdist =b41 'prog2 'W21 'SYMBOL Bo =b42 'lean back offset for backwards Baldur SYMBOL TOF =b43 'Toes Offset Front 1-9 'W22 SYMBOL W22random =w22 'b44,b45 SYMBOL W22random0 =b44 'W23 SYMBOL DoAt =b46 'Pointer in Do SYMBOL InDo =b47 'flag for In a Do 'W24 SYMBOL mindAt =b48 ' SYMBOL mindSub =b49 ' 'W25 SYMBOL RHcmnd =b50 'controls Hip Centres for RideHeight 0-9 in 2-NewBehave: SYMBOL RHcmndold =b51 'last Ride height cmnd 'Thor 'W26 'W27 SYMBOL W27temp =w27 'prog1 SYMBOL W27temp0 =b54 'prog1 SYMBOL W27temp1 =b55 'prog1 SYMBOL temp54 =b54 ' SYMBOL temp55 =b55 'prog1 SYMBOL LED_PWM_Doing =1020 'bright - only used in #1 SYMBOL LED_PWM_Medium =200 'not used SYMBOL LED_PWM_Ready =50 'only used at start of #0Commnader SYMBOL LED_PWM_Dim =10 'not used '--------- 'Variables - Storage - peek and poke '------------------- '200 56 to 255 ($38 to $FF) SYMBOL RAM_temp0 =56 'first non variable RAM location SYMBOL RAM_P1_f8_flags =57 'Prog1 flags 'turned Left bit 0 '1=last turned Left, 0=Right ''SYMBOL RAM_holedetectR =58 ' ''SYMBOL RAM_holedetectL =59 ' SYMBOL RAM_obstaclesR =60 'map SYMBOL RAM_obstaclesL =61 'map SYMBOL RAM_lightR =62 'whisker ambient light level Right SYMBOL RAM_lightL =63 'whisker ambient light level Left SYMBOL RAM_UStoonear =64 SYMBOL RAM_USawareAt =65 SYMBOL RAM_USunits_cm_ =66 SYMBOL RAM_USlast =67 SYMBOL RAM_WhiskerR =68 SYMBOL RAM_WhiskerL =69 SYMBOL RAM_WhiskerRlit =70 SYMBOL RAM_WhiskerLlit =71 SYMBOL RAM_FeelerR =72 SYMBOL RAM_FeelerL =73 SYMBOL RAM_FeelerRlit =74 SYMBOL RAM_FeelerLlit =75 SYMBOL RAM_Wthresh =76 SYMBOL RAM_Fthresh =77 'SYMBOL RAM_Sspeed =78 'SYMBOL RAM_randvarLo =68 'SYMBOL RAM_randvarHi =69 'SYMBOL RAM_randseedlo =70 'SYMBOL RAM_randseedhi =71 SYMBOL EEPROM_LHC =255 'logical value SYMBOL EEPROM_LAC =254 'logical value SYMBOL EEPROM_RHC =253 'logical value SYMBOL EEPROM_RAC =252 'logical value SYMBOL EEPROM_TOF =251 'Toes Offset Front 1-9 SYMBOL EEPROM_FLcmnd =250 'Foot Lift movement 1-9 SYMBOL EEPROM_FPcmnd =249 'Pace ForwardBack movement 1-9 SYMBOL EEPROM_FTcmnd =248 'Foot Turn movement 1-9 SYMBOL EEPROM_Speeds =247 'HiNib=speedmax(9), LoNib=speed(1) SYMBOL EEPROM_RHcmnd =246 'RideHeight 1-9, (Baldur FUScmnd) '245 Bo 'Back lean back Baldur SYMBOL EEPROM_kickcmnd =244 SYMBOL EEPROM_f8_behaves =243 SYMBOL EEPROM_Wthresh =242 SYMBOL EEPROM_Fthresh =241 SYMBOL EEPROM_USawarenear =240 'start of last 16 byte slot SYMBOL EEPROM_ActsEnd =239 'end of slot 06 '================================================== 'SERVOS - ACTUAL values from @ - values are in 10us units 'GWS S03 [39.5 x 20.0 x 35.6 42g] 0.23sec 3.4@4.8v 4@6v '================================================== SYMBOL SRHmin =126 '0 Right Hip Max foot up, full body down SYMBOL SRHmid =168 '42 Right Hip Stand feet flat SYMBOL SRHmax =210 '86 Right Hip Max foot down leg stop SYMBOL SRAmax =231 'Right Ankle Max out servo stop SYMBOL SRAF =224 'Toes Forward 'SYMBOL SRAFWmax =175 '+33 back toe hits other foot SYMBOL SRAFWmid =162 '+20 SYMBOL SRAFWmin =147 '+5 TOS=5 SYMBOL SRAmid =142 'Right Ankle Mid ahead - walk range +-20 TOS=5 SYMBOL SRABWmin =138 '-5 TOS=5 SYMBOL SRABWmid =112 '-20 'SYMBOL SRABWmax =101 '-41 front toe hits other foot SYMBOL SRAB =61 'Toes Back SYMBOL SRAmin =55 'Right Ankle Min in servo stop SYMBOL SLHmax =197 '0 Left Hip Max foot up, full body down 67 SYMBOL SLHmid =152 '45 Left Hip Stand feet flat 125 SYMBOL SLHmin =104 '93 Left Hip Max foot down leg stop 157 SYMBOL SLAmin =58 'Left Ankle Min out servo stop SYMBOL SLAF =67 'Toes Forward 'SYMBOL SLAFWmax =111 '-33 back toe hits other foot SYMBOL SLAFWmid =124 '-20 SYMBOL SLAFWmin =139 '-5 TOS=5 SYMBOL SLAmid =144 'Left Ankle Mid ahead - walk range +-20 TOS=5 SYMBOL SLABWmin =149 '+5 TOS=5 SYMBOL SLABWmid =164 '+20 'SYMBOL SLABWmax =178 '+33 front toe hits other foot SYMBOL SLAB =231 'Toes Back SYMBOL SLAmax =238 'Left Ankle Max in servo stop 'Left toes forward is -ve 'Left leg out is -ve 'Right toes forward is +ve 'Right leg out is +ve '================================================== 'LOGICAL 'toes forward is +ve 'leg out is +ve SYMBOL RAmax =SRAmax '231 -55 =176 SYMBOL RAFWmid =SRAFWmid '162 SYMBOL RAFWmin =SRAFWmin SYMBOL RAmid =SRAmid '142 SYMBOL RABWmin =SRABWmin SYMBOL RABWmid =SRABWmid '112 SYMBOL RAmin =SRAmin '55 SYMBOL RHmin =SRHmin '126 -213 =87 'foot up SYMBOL RHmid =SRHmid '168 SYMBOL RHmax =SRHmax '210 'foot down 'note max min reversals for left SYMBOL LAmax =255 -SLAmin '255 -58 =197 197 -17 =180 SYMBOL LAFWmid =255 -SLAFWmid '255 -124 =131 SYMBOL LAFWmin =255 -SLAFWmin SYMBOL LAmid =255 -SLAmid '255 -144 =111 SYMBOL LABWmin =255 -SLABWmin SYMBOL LABWmid =255 -SLABWmid '255 -164 =91 SYMBOL LAmin =255 -SLAmax '255 -238 =17 SYMBOL LHmin =255 -SLHmax '58 - 152 =94 'foot up SYMBOL LHmid =255 -SLHmid '103 SYMBOL LHmax =255 -SLHmin '151 'foot down '--------------- 'for servo numbering in CaseAdjust: SYMBOL RA =0 SYMBOL RH =1 SYMBOL LA =2 SYMBOL LH =3 '-------------------------------------------------------------- SYMBOL DSframe =15 'default SFrame, LOOPs at ~40Hz/25ms SYMBOL Fclear =20 'minimum for toes to miss when walking SYMBOL f_RfF =1 '1=>Right Foot Forward SYMBOL TSO =8 'Toe Stand Offset - so toes clear each other, min 3 SYMBOL FLWmin =55 'Minimum Foot Lift to clear toes when walking SYMBOL FLTmin =FLWmin +15 'minimum lift in turns '================================================== ' SENSORS '================================================== PingSensors: '----------- ' At sea level sound travels through air at 1130 feet per second. ' This equates to 1 inch in 73.746 uS, or 1 cm in 29.034 uS. ' ' Since the Ping sensor measures the time required for the sound wave ' to travel from the sensor and back. The result is divided by two to ' remove the return portion of the echo pulse, then multiplied by 10 ' to convert 10uS resolution to uS. ' The final raw result is converted to cm.or inches ' uS * 10/2/73.746in => * 0.01356 => * 4443/65536 => ** 4443 ' uS * 10/2/29.034cm => * 0.03444 => * 11286/65536 => ** 11286 'SYMBOL uS10toinch =4443 ' 10 / 58.068 (with **) 'SYMBOL uS10tocm =11286 ' 10 / 147.492 (with **) SYMBOL uS10tocm4mHz =11286 ' 10 / 147.492 (with **) SYMBOL cmtoinch =25802 ' /2.54 -> *25802 /65536 -> **25802 'PULSIN resolution @16MHz=2.5uS SYMBOL USscalecm =uS10tocm4mHz /4 'pulsin units 2.5uS @16MHz SYMBOL pingtrig =6 '15uS @16Mhz 'SRF05 'If no echo SRF05 ultrasonic sensor times out at 32ms 'HC-SR04 'If no echo HC-SR04 ultrasonic sensor never times out. 'The HC-SR04 starts the return pulse too quickly for a PicAxe20m2 @4Mhz 'to detect the start of the pulse. It needs to run at least @8MHz. 'Also if the sensor never gets a return echo from an obstacle the 'return pulse never ends and the PULSIN timer has to overflow before 'it returns a value. At 8MHz the timer resolution is 5us. The timer 'is 16 bits which means each reading takes '65,536 * 5us =327680 'which is about 1/3 of a second. This is a long time to wait between 'steps and makes walking very slow. 'Increasing the clock speed to 16MHz means the timer resolution is '2.5us and it times out in 65536 *2.5us = 163990us or about 0.16 'of a second which is much better. 'So SETFREQ m16 should be used (max for 40x2) '============================================================== TVR010_PicAxe_IR_controller: '--------------------------- 'Before use, the transmitter must be programmed with the ‘Sony’ transmit code. '1. Insert 2 AAA size batteries, preferably alkaline. '2. Press ‘S’ and ‘B’ at the same time. S is in the centre of the arrows. ' The top left red LED should light. '3. Press ‘0’. The LED should flash. '4. Press ‘1’. The LED should flash. '5. Press ‘3’. The LED should go out. '6. Press the red power button (top right). '------------------------------------------- 'IRin cmnds PicAxe controller 'DO NOT PRESS OTHER KEYS 'ie [A] [B] [C] [D] [E] [F] [G] 'They change the Mode and [B] has to be pressed to change back. '[square] [triangle] [()] [L] [X] [backwards F] have no effect SYMBOL KEY_POWER = 21 'Sleep SYMBOL KEY_UP = 16 '[Fd] Step Forward [9][Fd]=set vitality Behaviour to faster SYMBOL KEY_DOWN = 17 '[Bk] Step Backward [9][Bk]=set vitality Behaviour to slower SYMBOL KEY_RIGHT = 18 '[Rt] Step Right SYMBOL KEY_LEFT = 19 '[Lt] Step Left SYMBOL KEY_BAR = 96 '[f|] learn an Act, next [key] selects an Act SYMBOL KEY_TENT = 54 '[f^] next [key] selects a Subroutine-Act SYMBOL KEY_VERT_CROSS = 37 'use synonym for easier coding SYMBOL KEY_VCROSS = 37 '[f+] Modify Mode {when routine included} ' [+] set USAwareAt in DUSawareAt ' [-] set UStoonear in DUStoonear ' {[Fd] alter PaceCentre in DpaceC} ' {[Bk] alter PaceCentre in DpaceC} ' {[Rt] alter RollCentre in DrollC} ' {[Lt] alter RollCentre in DrollC} ' { [-][+] to adjust } ' [Key_POWER] to quit SYMBOL KEY_DIAG_CROSS = 20 'use synonym for easier coding SYMBOL KEY_XCROSS = 20 '[fX] transfer EEPROM to PC for including in programs ' -- Subroutine-Act and Commands -- SYMBOL KEY_1 = 0 '[1] [f^][1]=>RockADo [9][1]=set speed slow SYMBOL KEY_2 = 1 '[2] [9][2]=set speed medium SYMBOL KEY_3 = 2 '[3] [9][3]=set speed fast SYMBOL KEY_4 = 3 '[4] [9][4]=set US behaviour to timid SYMBOL KEY_5 = 4 '[5] [9][5]=set US behaviour to normal SYMBOL KEY_6 = 5 '[6] [9][6]=set US behaviour to bold SYMBOL KEY_7 = 6 '[7] [9][7]=disable Whiskers test SYMBOL KEY_8 = 7 '[8] [9][8]=disable Ultrasonic test SYMBOL KEY_9 = 8 '[9] set Behaviour modes [9][9]=set US behaviour to User SYMBOL KEY_MINUS = 98 '[-] enable & test Whisker sensors and re-act, R_Whiskers: SYMBOL KEY_0 = 9 '[0] WANDER [9][0]=set vitality Behaviour to normal SYMBOL KEY_PLUS = 11 '[+] enable & test Ping sensor and re-act, R_Ping: '================================================================= ' INITIALISATION '========================== Init: hserptr =W2temp 'get back pointer SERTXD("{1",rootcmnd,cmnd,",") PWMOUT EyeLLED,255,LED_PWM_Doing PWMOUT EyeRLED,255,LED_PWM_Doing f8_doServos =$F0 'F=pulse servos, 0=done move f_MoveAborted =0 AdjPosture: 'sertxd("LHat",#LHat," RHat",#RHat," ",cr) IF f_Bmodified=1 THEN GOSUB NewBehave '---------------------------------------------------- Qstanding: IF standOnLR=%11 AND f_b_react=1 THEN IF senseLtoe=0 OR senseRtoe=0 THEN GOSUB p1000_sshhh GOSUB Rhole ENDIF ENDIF 'Qfell: 'tip sesnsors not fitted 'Check if fallen ' READADC S.A1,temp 'READADC needs port.pin not a symbol ' IF tempTipU THEN ' GOSUB sshhh ' ENDIF '==================================================== ' COMMANDER '==================================================== SELECT RootCmnd 'CaseTurn: CASE "t" 'turn SELECT cmnd CASE "m" GOSUB Tm 'Turn Memory same way as last time CASE "o" GOSUB Tother 'Turn Otherway from last time CASE "a" GOSUB Ta 'Turn Away from leading foot CASE "t" GOSUB Tt 'Turn To leading foot CASE "r" GOSUB Tr 'Turn on the spot CASE "l" GOSUB Tl 'Turn on the spot ELSE GOSUB sshhh ENDSELECT 'CaseActions: CASE "a" SELECT cmnd CASE "1","b","2","e","3","o","4","v" RootCmnd ="v" GOTO Run2 'and here for IR 'CASE "1","b" GOSUB bip 'and here for IR 'CASE "2","e" GOSUB whee 'and here for IR 'CASE "3","o" GOSUB whoa 'and here for IR 'CASE "4","v" GOSUB beep100 'and here for IR CASE "5","S" GOSUB StampRL CASE "6","W" GOSUB WaveL CASE "7","s" RHcmnd ="0" GOSUB NewBehave GOSUB PH_SLR CASE "8","c" RHcmnd ="4" GOSUB NewBehave GOSUB PH_SLR CASE "9","t" RHcmnd ="8" GOSUB NewBehave GOSUB PH_SLR CASE "0","A" mindAt =mindstart 'same as "A" and here for IR CASE "+","E" cmnd ="E" :GOTO RUN2 'and here for IR ELSE GOSUB sshhh ENDSELECT 'CasePose: ' CASE "p" ' SELECT cmnd 'Baldur CASE "F" GOSUB poseForwardsFull 'Baldur CASE "B" GOSUB poseBackFull 'Baldur CASE "f" GOSUB poseForwards 'Baldur CASE "b" GOSUB poseBack 'Baldur CASE "u" GOSUB poseUp 'standup straight ' ELSE GOSUB sshhh ' ENDSELECT 'CaseSense CASE "$" SELECT cmnd CASE "+" GOSUB QWhiskerFeelers :GOSUB NewMapWhiskersFeelers :GOSUB Robstacle 'from IR, react on CASE "-" GOSUB Qground :GOSUB Rhole 'from IR, react on CASE "0" f_b_react =0 :f_b_autosense =0 'for IR VCROSS="$" CASE "1" f_b_react =1 'for IR VCROSS="$" CASE "2","a" f_b_autosense =1 'for IR VCROSS="$" CASE "U" GOSUB Qping :GOSUB Robject CASE "W" GOSUB Qwhiskers :GOSUB NewMapWhiskers :GOSUB Robstacle CASE "F" GOSUB Qfeelers :GOSUB NewMapFeelers :GOSUB Robstacle CASE "G" GOSUB Qground :GOSUB Rhole ELSE GOSUB sshhh ENDSELECT '$ CASE "?" SELECT cmnd CASE "U" GOSUB Qping : GOTO Run0 '2023-01-03 CASE "W" GOSUB Qwhiskers : GOSUB NewMapWhiskers :GOTO Run0 '2023-01-03 CASE "F" GOSUB Qfeelers : GOSUB NewMapFeelers :GOTO Run0 '2023-01-03 ELSE GOSUB sshhh ENDSELECT ELSE SELECT cmnd CASE "F" GOSUB Fd CASE "B" GOSUB Bk CASE "R" GOSUB TurnBehaviour : GOSUB Rt CASE "L" GOSUB TurnBehaviour : GOSUB Lt CASE "K" GOSUB KickShuffle CASE "H" GOSUB Hlt ' CASE "V" GOSUB bip CASE "I" GOSUB InitLegs CASE "M" GOSUB Move 'used in Wait; also from LoadBehaviour: and 'from CaseBehave to update values by NewBehave: 'could have used say "N" and gosub NewBehave: CASE "@" GOSUB SETUP ELSE GOSUB sshhh ENDSELECT ENDSELECT 'don't Qtoes if only on one foot, should never happen with intrinsic Poses IF standOnLR=%11 AND f_b_autosense=1 THEN GOSUB Qground 'prints g,% sets sense0 from toes IF sense0<>%11 THEN GOSUB Autohole IF f_b_react=1 THEN GOSUB QWhiskerFeelers :GOSUB NewMapWhiskersFeelers :GOSUB Autoobstacle ENDIF IF f_b_Uon=1 THEN GOSUB Qping :GOSUB Autoobject ENDIF ENDIF 'check for drop/object and ReaAct IF RHcmnd ="0" THEN : f8_doServos =$00 : ENDIF 'don't pulse servos if squating Run0: W2temp =hserptr 'Preserve pointer RUN 0 Run2: W2temp =hserptr 'Preserve pointer RUN 2 '==================================================== ' BEHAVIOUR '==================================================== NewBehave: READ EEPROM_LAC,LAC LAC =LAC +TOF READ EEPROM_RAC,RAC RAC =RAC +TOF sertxd("newbehave") Sspeed =Scmnd -"0" MIN 1 'otherwise MOVE: hangs ;L 93, R86 max travel FP =FPcmnd -"1" *2 + TSO 'TSO=8 '1-0/8 2-2/10 3-4/12 3-6/14 4-8/16 5-10/18 6-12/20 7-14/22 8-18/24 9-20/26 temp0 =26 -RHcmnd -"0" '26 is max FP, limit pace for higher ride FP =FP MAX temp0 'otherwise can fall over FT =FTcmnd -"1" *2 + TSO 'TSO=8 '1-0/8 2-2/10 3-4/12 3-6/14 4-8/16 5-10/18 6-12/20 7-14/22 8-18/24 9-20/26 temp0 =Sspeed *5 +FLWmin 'FLWmin=55 Sspeed min 1 =>min 60 FL =FLcmnd -"1" *10 MIN temp0 '1-60 2-60 3-60 4-60 5-60 6-60 7-70 8-80 9-90 LHC =RHcmnd -"0" *11 +LHmin MAX LHmax '0-58 1-69 2-80 3-91 4-102 5-113 6-124 7-135 8-146 (max 151) 9-157 RHC =RHcmnd -"0" *11 +RHmin MAX RHmax '0-126 1-137 2-148 3-159 4-170 5-181 6-192 7-203 8-214 (max 210) 9-226 'sertxd("LHC=",#LHC," RHC=",#RHC,cr) 'needed for when move aborted when fallen ' W2temphi =LAat +40 -LAC ' W2templo =RAat +40 -RAC ' IF W2templo>W2temphi THEN :f_Rfwd =1 :ELSE f_Rfwd =0 :ENDIF f_Bmodified =0 RETURN '---------------------------------------------------- TurnBehaviour: 'R,L FL =FL MIN FLTmin f_Bmodified =1 RETURN '==================================================== ' MIND '========================== NewMapWhiskersFeelers: sense0 =0 MapWhiskersFeelers: GOSUB MapWhiskers GOSUB MapFeelers RETURN NewMapWhiskers: sense0 =0 MapWhiskers: PEEK RAM_Wthresh ,temp55 PEEK RAM_whiskerL ,W2temp0 'full dark =255 PEEK RAM_whiskerLlit,W2temp1 'full lit =0 temp54 =W2temp0 MIN W2temp1 -W2temp1 IF temp54>temp55 THEN :bit1 =1 :HIGH whiskerLLED :ENDIF PEEK RAM_whiskerR, W2temp0 'full dark =255 PEEK RAM_whiskerRlit,W2temp1 'full lit =0 temp54 =W2temp0 MIN W2temp1 -W2temp1 IF temp54>temp55 THEN :bit0 =1 :HIGH whiskerRLED :ENDIF sertxd("WLR%",#bit1,#bit0,CR) ' %LR 1=>obstacles 0=>free '2023-01-03 RETURN NewMapFeelers: sense0 =0 MapFeelers: PEEK RAM_Fthresh ,temp55 PEEK RAM_FeelerL ,W2temp0 'full dark =255 PEEK RAM_FeelerLlit,W2temp1 'full lit =0 temp54 =W2temp0 MIN W2temp1 -W2temp1 IF temp54>temp55 THEN :bit1 =1 :HIGH feelerLLED :ENDIF PEEK RAM_FeelerR ,W2temp0 'full dark =255 PEEK RAM_FeelerRlit,W2temp1 'full lit =0 temp54 =W2temp0 MIN W2temp1 -W2temp1 IF temp54>temp55 THEN :bit0 =1 :HIGH feelerRLED :ENDIF sertxd("FLR%",#bit1,#bit0,CR) ' %LR 1=>obstacles 0=>free '2023-01-03 RETURN '==================================================== ' SENSES '========================== '---------------------------------------- #rem setUSawares: SELECT subcmnd CASE "m" GOSUB setUSawares_m 'set thresholds manually CASE "+" GOSUB QRecordGetCmnd SELECT cmnd CASE "0" TO "9" ' temp =cmnd -"0" :temp =temp *2 ' PEEK RAMUSunits_cm,i_temp ' IF i_temp=1 THEN :temp =temp *5 /2 ENDIF temp =cmnd -"0" *5 'units cm POKE RAMUSawareAt,temp ENDSELECT CASE "-" GOSUB QRecordGetCmnd SELECT cmnd CASE "0" TO "9" ' temp =cmnd -"0" :temp =temp *2 ' PEEK RAMUSunits_cm,i_temp ' IF i_temp=1 THEN :temp =temp *5 /2 ENDIF temp =cmnd -"0" *5 'units cm POKE RAMUStoonear,temp ENDSELECT CASE "i" POKE RAMUSunits_cm_,1 'inches CASE "c" POKE RAMUSunits_cm_,0 'cm ELSE GOSUB sshhh ENDSELECT RETURN '---------------------------------------- setUSawares_m: IF f_IRcmnd=1 THEN IRIN inIR,cmnd 'setup entered from IRremote ELSE GOSUB GetCmnd ENDIF GOSUB beep50 'got cmnd W2temp =0 _getUSdist: GOSUB Qping SERTXD("US",#usdist,CR) IF usdist=0 THEN GOSUB badkey GOTO _getUSdist 'loop until valid reading ENDIF 'SERTXD("cmnd",#cmnd,CR) SELECT cmnd CASE "+",KEY_PLUS POKE RAMUSawareAt,usdist 'SERTXD("KEY_PLUS",CR) 'SERTXD("AwareAt=",#usdist,CR) CASE "-",KEY_MINUS POKE RAMUStoonear,usdist 'SERTXD("KEY_MINUS",CR) 'SERTXD("TooClose=",#usdist,CR) CASE "Q",KEY_POWER,Esc 'Quit GOSUB beep50 'done 'SERTXD("KEY_POWER",CR) RETURN 'RETURN ELSE GOSUB badkey ENDSELECT GOTO setUSawares_m #endrem '----------------- Qping: 'Query Ultrasonic Sensor, read into USdist POKE RAM_USlast,usdist LOW pingpin ' make trigger 0-1-0 PULSOUT pingpin,pingtrig ' activate sensor PULSIN pingpin,1,W2temp ' measure high(=1) echo pulse in units, ' units are 10us@4MHz, 2.5us@32MHz ' pulsin rolls over at 65536counts =>0 ' ie 0.65536sec @ 4MHz(10uS) too long to wait if nothing there ' 0.16399sec @16MHz(2.5uS) tolerable ' so use 16MHz for HCSR04 ' SRF05 auto times out at 36ms and returns 0, good. ' PEEK RAMUSunits_cm_,temp ' IF temp=0 THEN W2temp =W2temp ** USscalecm 'scale time to cm ' ELSE ' W2temp =W2temp ** cmtoinch ' ENDIF IF W2temp=0 THEN ' if timeout then usdist =255 ' set to max distance ELSE usdist =W2temp MAX 255 ENDIF SERTXD("U(",#usdist,"cm)") usdist =usdist /5 'convert to 5cm/2inch units SERTXD(#usdist,CR) ' %LR 0=>obstacles 1=>free RETURN '---------------------------------------------------- QWhiskerFeelers: 'SYMBOL whiskerL =A.5 'READADC needs port.pin not a symbol 'SYMBOL whiskerR =D.0 'READADC needs port.pin not a symbol 'SYMBOL feelerL =D.6 'READADC needs port.pin not a symbol or pinX.Y 'SYMBOL feelerR =D.5 'READADC needs port.pin not a symbol or pinX.Y HIGH whiskerLLED HIGH whiskerRLED HIGH feelerLLED HIGH feelerRLED GOSUB ReadWhiskersFeelers POKE RAM_whiskerLlit,W2temp1 POKE RAM_whiskerRlit,W2temp0 'sertxd("Wlit",#W2temp1,",",#W2temp0) POKE RAM_feelerLlit,W27temp1 POKE RAM_feelerRlit,W27temp0 'sertxd("Flit",#W2temp1,",",#W2temp0) LOW whiskerLLED LOW whiskerRLED LOW feelerLLED LOW feelerRLED GOSUB ReadWhiskersFeelers POKE RAM_whiskerL,W2temp1 POKE RAM_whiskerR,W2temp0 'sertxd("Wdark",#W2temp1,",",#W2temp0,cr) POKE RAM_feelerLlit,W27temp1 POKE RAM_feelerRlit,W27temp0 'sertxd("Fdark",#W2temp1,",",#W2temp0,cr) RETURN '---------------------------------------------------- ReadWhiskersFeelers: W2temp =0 W27temp =0 for cmnd =0 to 6 READADC A.5,sense0 : W2temp1 =W2temp1 MIN sense0 READADC D.0,sense0 : W2temp0 =W2temp0 MIN sense0 READADC D.6,sense0 : W27temp1 =W27temp1 MIN sense0 READADC D.5,sense0 : W27temp0 =W27temp0 MIN sense0 next cmnd RETURN '---------------------------------------------------- Qwhiskers: 'SYMBOL whiskerL =A.5 'READADC needs port.pin not a symbol 'SYMBOL whiskerR =D.0 'READADC needs port.pin not a symbol sense0 =0 HIGH whiskerLLED HIGH whiskerRLED GOSUB ReadWhiskers POKE RAM_whiskerLlit,W2temp1 POKE RAM_whiskerRlit,W2temp0 sertxd(CR,"Wlit L",#W2temp1,",R",#W2temp0) LOW whiskerLLED LOW whiskerRLED GOSUB ReadWhiskers POKE RAM_whiskerL,W2temp1 POKE RAM_whiskerR,W2temp0 sertxd(CR,"WdarkL",#W2temp1,",R",#W2temp0,CR) RETURN '---------------------------------------------------- ReadWhiskers: W2temp =0 for cmnd =0 to 6 READADC A.5,sense0 : W2temp1 =W2temp1 MIN sense0 'whiskerL READADC D.0,sense0 : W2temp0 =W2temp0 MIN sense0 'whiskerR next cmnd RETURN '---------------------------------------------------- Qfeelers: 'SYMBOL Lfeeler =D.6 'READADC needs port.pin not a symbol or pinX.Y 'SYMBOL Rfeeler =D.5 'READADC needs port.pin not a symbol or pinX.Y HIGH feelerLLED HIGH feelerRLED GOSUB ReadFeelers POKE RAM_FeelerLlit,W2temp1 POKE RAM_FeelerRlit,W2temp0 sertxd(CR,"Flit L",#W2temp1,",R",#W2temp0) LOW feelerLLED LOW feelerRLED GOSUB ReadFeelers POKE RAM_FeelerL,W2temp1 POKE RAM_FeelerR,W2temp0 sertxd(CR,"FdarkL",#W2temp1,",R",#W2temp0,CR) RETURN '---------------------------------------------------- ReadFeelers: W2temp =0 for cmnd =0 to 6 READADC D.6,sense0 : W2temp1 =W2temp1 MIN sense0 'feelerL READADC D.5,sense0 : W2temp0 =W2temp0 MIN sense0 'feelerR next cmnd RETURN '---------------------------------------------------- Qground:'->sense0 'Q on Ground=1 "$G", auto if f_bg_Qtoes=1 sertxd("Qg") sense0 =0 FOR temp55 =0 TO 10 'about 40 msec bit1 =bit1 OR senseLtoe bit0 =bit0 OR senseRtoe IF sense0=3 THEN EXIT PAUSE 8 '4ms @m16 max about 0.1 sec NEXT 'temp55 '# sertxd("g@",#temp55,"%",#bit1,#bit0," ") RETURN '==================================================== ' REACTIONS '==================================================== Robject: SERTXD("ru") IF f_b_react=0 THEN SERTXD("q") RETURN ENDIF AutoObject: '2023-01-03 PEEK RAM_USawareAt,sense0 IF usdistobstacles 0=>free '2023-01-03 PAUSE 100 IF sense0=%11 THEN :ReactAt =OLR :ENDIF IF sense0=%10 THEN :ReactAt =OL_ :ENDIF IF sense0=%01 THEN :ReactAt =O_R :ENDIF RETURN '---------------------------------------------------- Rhole: 'sens0 set in Qground: SERTXD("rg") IF f_b_react=0 THEN SERTXD("q") RETURN ENDIF Autohole: GOSUB Bip GOSUB Qground IF sense0<>%11 THEN GOSUB KickShuffle GOSUB Qground IF sense0=%11 THEN RETURN :ENDIF GOSUB Qground IF sense0<>%11 THEN GOSUB KickShuffle GOSUB Qground IF sense0=%11 THEN RETURN :ENDIF sertxd(" hole",CR) ' %LR 0=>holes 1=>on ground '2023-01-03 IF sense0=%00 THEN :ReactAt =HLR :ENDIF '2023-01-03 IF sense0=%01 THEN :ReactAt =HL_ :ENDIF '2023-01-03 IF sense0=%10 THEN :ReactAt =H_R :ENDIF '2023-01-03 RETURN '==================================================== ' ACTS '==================================================== WaveL: standOnLR=%01 'sertxd("WaveR") Sspeed =Sspeed MAX 2 RHto =RHmax LHto =LHmin hframes =12 'about 1/2 sec GOSUB Move RAto =RAmid LAto =LAmid hframes =12 'about 1/2 sec GOSUB Move hframes =12 'about 1/2 sec GOSUB Move Sspeed =8 LAto =LAmid +60 GOSUB Move LAto =LAmid -60 GOSUB Move LAto =LAmid +60 GOSUB Move LAto =LAmid -60 GOSUB Move LAto =LAmid +60 GOSUB Move LAto =LAmid -60 GOSUB Move Sspeed =2 GOSUB PT_HH GOSUB PH_SLR f_Bmodified =1 RETURN '==================================================== ' ACTIONS '========================== InitLegs: 'Only done on Cold start after Reset or"I". 'f_LAdo, f_LHdo, f_RHdo, f_RAdo, hframes are all 0 f_LApulse =0 f_RApulse =0 RHcmnd ="4" 'Crouch Scmnd ="1" GOSUB NewBehave GOSUB PH_SLR 'Stand - don't move ankles GOSUB PH_SR 'Stand on Right - don't move ankles f_LApulse =1 f_RApulse =1 RAat =RAC +10 'Servo Right Ankle At LAat =LAC -10 'Servo Left Ankle At FOR cmnd =0 TO 25 'rotate feet to Aat, give time for servos to get there GOSUB TellServos PAUSE 30 'a bit slower NEXT RAto =RAat LAto =LAat GOSUB PH_SLR 'Stand RHcmnd ="0" 'Sit GOSUB NewBehave GOSUB PH_SLR 'Stand f8_doServos =0 f_Rfwd =1 RETURN '---------------------------------------------------- StampRL: 'sertxd("StampRL") GOSUB StampR GOSUB StampL RETURN '----------------------- StampR: 'sertxd("StampR") hframes =12 'about 1/2 sec GOSUB PH_SL Sspeed =Sspeed +3 MAX 8 hframes =12 'about 1/2 sec GOSUB PH_SLR f_Bmodified =1 RETURN '----------------------- StampL: 'sertxd("StampL") hframes =12 'about 1/2 sec GOSUB PH_SR Sspeed =Sspeed +3 MAX 8 hframes =12 'about 1/2 sec GOSUB PH_SLR f_Bmodified =1 RETURN '----------------------- KickShuffle: 'a6, ^6, K sertxd("k",kickcmnd) temp0 =kickcmnd -"0" *4 IF f_Rfwd =0 THEN LAto =LAat +temp0 RAto =RAat -temp0 ELSE LAto =LAat -temp0 RAto =RAat +temp0 ENDIF GOSUB Move IF f_Rfwd =0 THEN GOSUB PT_FB ELSE GOSUB PT_BF ENDIF GOSUB Move RETURN '==================================================== MOVEMENT: '==================================================== '----------------------- Hlt: 'stand with right foot forward IF f_Rfwd =1 THEN GOSUB PH_SLR 'don't Halt if at Halt RETURN ENDIF IF f_b_F =1 THEN GOSUB Fd 'make Rfwd ELSE GOSUB Bk 'make Rfwd ENDIF RETURN '----------------------- Fd: 'SERTXD("F") IF f_Rfwd =1 THEN GOSUB PH_SR GOSUB PT_FB f_Rfwd =0 ELSE GOSUB PH_SL GOSUB PT_BF f_Rfwd =1 ENDIF GOSUB PH_SLR f_b_F =1 RETURN '----------------------- Bk: 'SERTXD("B") IF f_Rfwd =1 THEN GOSUB PH_SL GOSUB PT_FB f_Rfwd =0 ELSE GOSUB PH_SR GOSUB PT_BF f_Rfwd =1 ENDIF GOSUB PH_SLR f_b_F =0 RETURN '----------------------- Tm: 'TurnMemory: PEEK RAM_P1_f8_flags,sense0 IF bit0=0 THEN Rt GOTO Lt RETURN '----------------------- Tother: 'TurnOther: PEEK RAM_P1_f8_flags,sense0 IF bit0=0 THEN Lt GOTO Rt RETURN '----------------------- Tt: 'TurnTo IF f_Rfwd=0 THEN Lt GOTO Rt '----------------------- Ta: 'TurnAway: IF f_Rfwd=1 THEN Lt 'else drop through to Rt GOTO Rt '----------------------- Tr: 'Turn Right on the spot IF RAat180 THEN 'ie if Tall RHmid 168 RHcrouch 170 temp55 =FTcmnd FTcmnd ="9" GOSUB NewBehave FTcmnd =temp55 f_Bmodified =1 ENDIF IF f_Rfwd=1 THEN GOSUB PH_SR GOSUB PT_FB f_Rfwd =0 ELSE GOSUB PH_SL GOSUB PT_0F f_Rfwd =1 ENDIF ELSE 'BR IF f_Rfwd=1 THEN GOSUB PH_SL GOSUB PT_F0 f_Rfwd =0 ELSE GOSUB PH_SR GOSUB PT_B0 f_Rfwd =1 ENDIF ENDIF GOSUB PH_SLR 'remember turn PEEK RAM_P1_f8_flags,sense0 :bit0 =0 :POKE RAM_P1_f8_flags,sense0 RETURN '----------------------- Lt: 'SERTXD("L") IF f_b_F=1 THEN 'FL IF RHC>180 THEN 'ie if Tall RHmid 168 RHcrouch 170 temp55 =FTcmnd FTcmnd ="9" GOSUB NewBehave FTcmnd =temp55 f_Bmodified =1 ENDIF IF f_Rfwd=0 THEN GOSUB PH_SL GOSUB PT_BF f_Rfwd =1 ELSE GOSUB PH_SR GOSUB PT_F0 f_Rfwd =0 ENDIF ELSE 'BL IF f_Rfwd=0 THEN GOSUB PH_SR GOSUB PT_0F f_Rfwd =1 ELSE GOSUB PH_SL GOSUB PT_0B f_Rfwd =0 ENDIF ENDIF GOSUB PH_SLR 'remember turn PEEK RAM_P1_f8_flags,sense0 :bit0 =1 :POKE RAM_P1_f8_flags,sense0 RETURN '==================================================== ' POSE PH_xx Hip, PT_xx Toe '==================================================== PH_SLR: 'Stand on Left + Right 'SERTXD("SLR ") LHto =LHC RHto =RHC standOnLR =%11 'any toe off is tested at Qfell GOTO MOVE PH_SR: 'Stand on Right 'SERTXD("SR ") 'lift L LHto =LHC MIN FL -FL MIN LHmin 'if can't lift L TU then down R difference temp0 =LHC -LHto 'L movement IF FL>temp0 THEN 'ie lift restricted temp0 =FL -temp0 'temp =restricted by RHto =RHC +temp0 max RHmax ENDIF standOnLR =%01 GOTO MOVE PH_SL: 'Stand on Left 'SERTXD("SL ") 'lift R RHto =RHC MIN FL -FL MIN RHmin 'if can't lift R TU then down L difference temp0 =RHC -RHto 'R movement IF FL>temp0 THEN 'ie lift restricted temp0 =FL -temp0 'temp =restricted by LHto =LHC +temp0 MAX LHmax ENDIF standOnLR =%10 GOTO MOVE '----Turning------------ PT_0F: LAto =LAC RAto =RAC +FT MAX 255 GOTO MOVE PT_F0: LAto =LAC +FT MAX 255 RAto =RAC GOTO MOVE PT_0B: LAto =LAC RAto =RAC MIN FT -FT GOTO MOVE PT_B0: LAto =LAC MIN FT -FT RAto =RAC GOTO MOVE '----------------------- PT_BF: LAto =LAC MIN FP -FP RAto =RAC +FP MAX 255 GOTO MOVE PT_FB: LAto =LAC +FP MAX 255 RAto =RAC MIN FP -FP GOTO MOVE '----------------------- PT_HH: 'Walk Toes Halt LAto =LABWmin RAto =RAFWmin GOTO MOVE '----------------------- PT_WW: 'toe walk walk safely, slide toes until they are <= mid-+TP for Tall 'sertxd("PT_WW") IF RAat>RAmid THEN 'sertxd(cr,"R>",#RAat,",",#RAmid,",") temp0 =RAmid +FP RAto =RAat MAX temp0 'sertxd(#RAto,cr) ENDIF IF RAatLAmid THEN 'sertxd(cr,"L>",#LAat,",",#LAmid,",") temp0 =LAmid +FP LAto =LAat MAX temp0 'sertxd(#LAto,cr) ENDIF IF LAatRAto RAat =RAat MIN Sspeed -Sspeed MIN RAto CASE RHto RHat =RHat MIN Sspeed -Sspeed MIN RHto CASE LAto LAat =LAat MIN Sspeed -Sspeed MIN LAto CASE LHto LHat =LHat MIN Sspeed -Sspeed MIN LHto CASE stance toe off ground IF f_b_autosense=1 THEN IF standOnLR=%10 THEN IF senseLtoe=0 THEN : topple =topple +1 :ENDIF ENDIF IF standOnLR=%01 THEN IF senseRtoe=0 THEN : topple =topple +1 :ENDIF ENDIF IF topple>0 THEN sertxd("t",#topple) ENDIF IF topple>50 THEN AbortMove 'on faster speeds topple never gets to 5 ENDIF 'f_bg_Qtoes W2pulselo = f_LAdo +f_LHdo +f_RHdo +f_RAdo IF W2pulselo<>0 THEN MoveCalcs hframes =hframes MIN 1 -1 IF hframes<>0 THEN MoveCalcs IF f_MoveAborted=1 THEN Run0 'quit Intrinsic Act now done AbortMove RETURN AbortMove: ' toe 0=off ground -> falling? so abortMove and do SLR sertxd("toppled") Sspeed =9 :f_Bmodified =1 : f_MoveAborted =1 : f_LApulse =0: f_RApulse =0 RHcmnd ="0" 'sitting LAto =LAat RAto =RAat RHcmnd ="0" GOSUB NewBehave GOTO MOVE '====================================================