'ManPOG87.BAS - 11/30/2000 - Randall M. Clague ' Instructions: CLS PRINT "Manual POGO Simulator - 11/30/2000 - Randall M. Clague" PRINT "Experimental Rocket Propulsion Society - www.erps.org" PRINT PRINT " Instructions: Bksp or ` = 0% throttle" PRINT " 1 - 9 = 10% - 90% throttle" PRINT " 0 = 100% throttle" PRINT " " + CHR$(24) + "/" + CHR$(25) + " = +/- 1% throttle" PRINT " +/- = speeds up / slows down simulation" PRINT "" PRINT " If arrow keys do not turn POGO, turn off NumLock" PRINT "" PRINT " Objective: Fly POGO to at least 300 meters altitude," PRINT " Hover (speed < 1 m/sec) for 1 second," PRINT " Translate right at least 300 meters" PRINT " (Altitude must stay above 300 meters)," PRINT " Hover (speed < 1 m/sec) for 1 second," PRINT " Soft land (speed < 2 m/sec)" PRINT "" PRINT " The computer will beep at each objective" PRINT "" PRINT " The computer will boop at you if you fail" PRINT PRINT "Are you ready (Y/N/Q)? " TimeIncrement = .01 UserReady: Ready$ = INKEY$ IF UCASE$(MID$(Ready$, 1, 1)) = "Y" THEN GOTO SimStart ELSEIF UCASE$(MID$(Ready$, 1, 1)) = "Q" THEN SYSTEM ELSEIF Ready$ = "" THEN GOTO UserReady ELSE PRINT Ready$ GOTO Instructions END IF SimStart: 'Manually fly ERPS POGO '12/7/98 - got updated weights from Gene & John '12/9/98 - add air resistance '1/20/98 - finish adding air resistance, zap bugs '1/31/99 - finished zapping bugs - pushing the envelope at 300 m x 300 m ' flight profile - haven't soft landed yet. ' '11/14/2000 - Use up and down arrows for throttle - done ' - Use left and right arrows for roll rate, not roll angle - done ' - Some dodge to give platform independent real time ' CLS ' ' Set up constants PI# = 4 * ATN(1) Gravity = 9.81 Height = 1.8 Side = .6 ' ' Set up variable initial states ' Throttle = 50 Axis.Theta.Absolute = 0 Prop = 37.6 DW = 44.1 Isp = 1000 Engine.Out = 1111 FOR n = 1 TO 8 Milestone(n) = 0 NEXT n ' Set up sim control keys ' ' Key(15) is defined as the + key - speeds up sim ' Key(16) is defined as the - key - slows down sim ' ' Key(17) is defined as Up Arrow - increases Throttle ' Key(18) is defined as Down Arrow - decreases Throttle ' ' Key(21) is defined as Left Arrow - yaws left ' Key(22) is defined as Right Arrow - yaws right ' ' 1-0 control throttle: 1 is 10%, 0 is full throttle, backspace is off KEY 15, CHR$(0) + CHR$(13) KEY 16, CHR$(0) + CHR$(12) ON KEY(15) GOSUB IncSimSpeed ON KEY(16) GOSUB DecSimSpeed KEY(15) ON KEY(16) ON KEY 17, CHR$(128) + CHR$(72) KEY 18, CHR$(128) + CHR$(80) ON KEY(17) GOSUB IncThrottle ON KEY(18) GOSUB DecThrottle KEY(17) ON KEY(18) ON KEY 21, CHR$(128) + CHR$(75) KEY 22, CHR$(128) + CHR$(77) ON KEY(21) GOSUB YawLeft ON KEY(22) GOSUB YawRight KEY(21) ON KEY(22) ON ' ' Start loop ' SCREEN 12 CLS Continue = 1 WHILE Continue Control$ = INKEY$ IF Control$ = CHR$(27) THEN STOP 'Set throttle IF Control$ = CHR$(8) THEN Throttle = 0 IF Control$ = "`" THEN Throttle = 0 IF Control$ = "1" AND Prop > 0 THEN Throttle = 10 IF Control$ = "2" AND Prop > 0 THEN Throttle = 20 IF Control$ = "3" AND Prop > 0 THEN Throttle = 30 IF Control$ = "4" AND Prop > 0 THEN Throttle = 40 IF Control$ = "5" AND Prop > 0 THEN Throttle = 50 IF Control$ = "6" AND Prop > 0 THEN Throttle = 60 IF Control$ = "7" AND Prop > 0 THEN Throttle = 70 IF Control$ = "8" AND Prop > 0 THEN Throttle = 80 IF Control$ = "9" AND Prop > 0 THEN Throttle = 90 IF Control$ = "0" AND Prop > 0 THEN Throttle = 100 IF Control$ = "A" AND Prop > 0 THEN Engine.Out = 889 IF Control$ = "a" AND Prop > 0 THEN Engine.Out = 889 ET = ET + TimeIncrement 'Figure out thrust setting Mass = Prop + DW Thrust = (Throttle / 50) * Mass * Gravity IF Thrust > Engine.Out THEN Thrust = Engine.Out END IF 'Figure out YawPos Axis.Theta.Absolute = Axis.Theta.Absolute + (YawRate * TimeIncrement) Thrust.X = SIN(Axis.Theta.Absolute * PI# / 180) * Thrust Thrust.Y = COS(Axis.Theta.Absolute * PI# / 180) * Thrust Prop = Prop - (Thrust / Isp) * TimeIncrement IF Prop < 0 THEN Throttle = 0 Prop = 0 END IF Mass = Prop + DW IF Altitude < 7000 THEN Air = 1.22 * 2 ^ (Altitude / -7000) ELSE Air = 1.22 * 2 ^ (Altitude / -7000) * 1.3 ^ ((Altitude - 7000) / -7000) END IF 'Calculate direction of travel IF ABS(Velocity.Y) < .000001 THEN Vector.Theta.Absolute = 0 ELSE Vector.Theta.Absolute = ATN(Velocity.X / Velocity.Y) / PI# * 180 END IF IF Velocity.Y < 0 THEN Vector.Theta.Absolute = Vector.Theta.Absolute + 180 END IF 'Calculate wind angle on vehicle Vector.Theta.Relative = Vector.Theta.Absolute - Axis.Theta.Absolute IF Vector.Theta.Relative < 0 THEN Vector.Theta.Relative = Vector.Theta.Relative + 360 END IF 'Calculate CD based on wind angle 'CD will range from ' 0.8 nose on less than M 0.8, 'to 1.6 nose on more than M 1.2, 'to 0.4 sideways less than M 0.8, 'to 0.8 sideways more than M 1.2, 'to 0.8 base first less than M 0.8, 'to 1.6 base first more than M 1.2. 'Mach 1 = 290 m/sec, M 0.8 = 230 m/sec, M 1.2 = 350 m/sec Velocity = SQR(Velocity.X ^ 2 + Velocity.Y ^ 2) IF Velocity <= 230 THEN CD = .4 + ABS(90 - (Vector.Theta.Relative MOD 180)) / 225 ELSEIF Velocity > 230 AND Velocity <= 350 THEN CD = .4 + ((Velocity - 230) / 300) + ABS(90 - (Vector.Theta.Relative MOD 180) / 225) + (ABS(90 - Vector.Theta.Relative MOD 180) / 225) * (Velocity - 230) / 120 ELSEIF Velocity > 350 THEN CD = .8 + ABS(90 - Vector.Theta.Relative MOD 180) / 112.5 END IF 'Calculate Area.Wetted based on wind angle ''Calculate Area.Wetted.* based on wind angle Area.Wetted.P = Side ^ 2 / 4 * COS(Vector.Theta.Relative * PI# / 180) Area.Wetted.Q = Side * Height / 2 * -SIN((Vector.Theta.Relative * PI# / 180) - ATN((Side / 2) / Height)) Area.Wetted.R = Side ^ 2 / 4 * COS(Vector.Theta.Relative * PI# / 180) Area.Wetted.S = Side * Height / 2 * SIN((Vector.Theta.Relative * PI# / 180) + ATN((Side / 2) / Height)) Area.Wetted.Base = Side ^ 2 * -COS(Vector.Theta.Relative * PI# / 180) IF Vector.Theta.Relative < ATN((Side / 2) / Height) * 180 / PI# THEN Area.Wetted = Area.Wetted.P + Area.Wetted.Q + Area.Wetted.R + Area.Wetted.S ELSEIF Vector.Theta.Relative < 90 THEN Area.Wetted = Area.Wetted.P + Area.Wetted.R + Area.Wetted.S ELSEIF Vector.Theta.Relative < 180 - ATN((Side / 2) / Height) * 180 / PI# THEN Area.Wetted = Area.Wetted.Base + Area.Wetted.S ELSEIF Vector.Theta.Relative < 180 + ATN((Side / 2) / Height) * 180 / PI# THEN Area.Wetted = Area.Wetted.Base ELSEIF Vector.Theta.Relative < 270 THEN Area.Wetted = Area.Wetted.Q + Area.Wetted.Base ELSEIF Vector.Theta.Relative < 360 - ATN((Side / 2) / Height) * 180 / PI# THEN Area.Wetted = Area.Wetted.Q + Area.Wetted.R + Area.Wetted.P ELSE Area.Wetted = Area.Wetted.P + Area.Wetted.Q + Area.Wetted.R + Area.Wetted.S END IF 'Drag Drag.X = .5 * Area.Wetted * -ABS(Velocity.X) * Air * Velocity.X * CD * ABS(SIN(Vector.Theta.Absolute * PI# / 180)) Drag.Y = .5 * Area.Wetted * -ABS(Velocity.Y) * Air * Velocity.Y * CD * ABS(COS(Vector.Theta.Absolute * PI# / 180)) Accel.X = (Thrust.X + Drag.X) / Mass Accel.Y = (Thrust.Y + Drag.Y) / Mass - Gravity Velocity.X = Velocity.X + Accel.X * TimeIncrement Velocity.Y = Velocity.Y + Accel.Y * TimeIncrement Distance = Distance + Velocity.X * TimeIncrement Altitude = Altitude + Velocity.Y * TimeIncrement IF Altitude > Altitude.Max THEN Altitude.Max = Altitude XPos = 100 + Distance / 2 YPos = 479 - (Altitude / 2) PSET (XPos, YPos) IF Milestone(1) = 0 THEN IF Altitude > 300 THEN Milestone(1) = 1 SOUND 900, 3 END IF END IF IF Milestone(1) = 1 THEN IF Milestone(2) = 0 THEN Velocity = SQR(Velocity.X ^ 2 + Velocity.Y ^ 2) IF Velocity < 1 THEN Milestone(2) = 1 Milestone.Timer = ET END IF END IF END IF IF Milestone(2) = 1 THEN IF Milestone(3) = 0 THEN Velocity = SQR(Velocity.X ^ 2 + Velocity.Y ^ 2) IF Velocity < 1 THEN IF ET > Milestone.Timer + 1 THEN Milestone(3) = 1 SOUND 900, 3 END IF ELSE Milestone(2) = 0 END IF END IF END IF IF Milestone(3) = 1 THEN IF Milestone(4) = 0 THEN IF Milestone(7) = 0 THEN IF Altitude < 300 THEN Milestone(4) = 1 SOUND 90, 9 'END END IF END IF END IF END IF IF Milestone(5) = 0 THEN IF Distance > 300 THEN Milestone(5) = 1 SOUND 900, 3 END IF END IF IF Milestone(5) = 1 THEN IF Milestone(6) = 0 THEN Velocity = SQR(Velocity.X ^ 2 + Velocity.Y ^ 2) IF Velocity < 1 THEN Milestone(6) = 1 Milestone.Timer = ET END IF END IF END IF IF Milestone(6) = 1 THEN IF Milestone(7) = 0 THEN Velocity = SQR(Velocity.X ^ 2 + Velocity.Y ^ 2) IF Velocity < 1 THEN IF ET > Milestone.Timer + 1 THEN Milestone(7) = 1 SOUND 900, 3 END IF ELSE Milestone(6) = 0 END IF END IF END IF ' Yaw Gauge LINE (550, 390)-(630, 470), 0, BF CIRCLE (590, 430), 40 LINE (590, 390)-(590, 400) LINE (550, 430)-(560, 430) LINE (620, 430)-(630, 430) LINE (590, 460)-(590, 470) LINE (590, 430)-STEP(39 * SIN(Axis.Theta.Absolute * PI# / 180), 39 * -COS(Axis.Theta.Absolute * PI# / 180)), 3 LOCATE 28, 58 PRINT "Blue = Yaw"; ' Velocity Vector Gauge IF SQR(Velocity.X ^ 2 + Velocity.Y ^ 2) > 0 THEN LINE (590, 430)-STEP(39 * Velocity.X / SQR(Velocity.X ^ 2 + Velocity.Y ^ 2), -39 * Velocity.Y / SQR(Velocity.X ^ 2 + Velocity.Y ^ 2)), 2 END IF LOCATE 29, 58 PRINT "Green = Flt"; LOCATE 30, 58 PRINT " Path Angle"; 'Yaw Rate Tape LINE (450, 400)-(530, 415), 0, BF LINE (490, 401)-(490 + (YawRate * .4), 407), 3, BF IF ABS(YawRate) < 10 THEN LINE (490, 408)-(490 + (YawRate * 4), 414), 3, BF ELSEIF YawRate > 0 THEN LINE (490, 408)-(530, 414), 3, BF ELSEIF YawRate < 0 THEN LINE (490, 408)-(450, 414), 3, BF END IF LINE (450, 400)-(530, 415), , B LINE (470, 401)-(470, 404) LINE (470, 414)-(470, 411) LINE (510, 401)-(510, 404) LINE (510, 414)-(510, 411) LOCATE 25, 58 PRINT "Yaw Rate"; ' Altimeter LINE (550, 288)-(630, 366), 0, BF CIRCLE (590, 327), 39 LINE (590, 288)-(590, 298) LINE (551, 327)-(561, 327) LINE (619, 327)-(629, 327) LINE (590, 356)-(590, 366) LINE (590, 327)-STEP(39 * SIN(Altitude * 36 * PI# / 180), -39 * COS(Altitude * 36 * PI# / 180)), 3 LINE (590, 327)-STEP(29 * SIN(Altitude * 3.6 * PI# / 180), -29 * COS(Altitude * 3.6 * PI# / 180)), 3 LINE (590, 327)-STEP(19 * SIN(Altitude * .36 * PI# / 180), -19 * COS(Altitude * .36 * PI# / 180)), 3 LINE (590, 327)-STEP(13 * SIN(Altitude * .036 * PI# / 180), -13 * COS(Altitude * .036 * PI# / 180)), 3 LOCATE 24, 71 PRINT "Altitude"; ' Trip Meter LINE (450, 288)-(530, 366), 0, BF CIRCLE (490, 327), 39 LINE (490, 288)-(490, 298) LINE (451, 327)-(461, 327) LINE (519, 327)-(529, 327) LINE (490, 356)-(490, 366) LINE (490, 327)-STEP(39 * SIN(Distance * 36 * PI# / 180), -39 * COS(Distance * 36 * PI# / 180)), 3 LINE (490, 327)-STEP(29 * SIN(Distance * 3.6 * PI# / 180), -29 * COS(Distance * 3.6 * PI# / 180)), 3 LINE (490, 327)-STEP(19 * SIN(Distance * .36 * PI# / 180), -19 * COS(Distance * .36 * PI# / 180)), 3 LINE (490, 327)-STEP(13 * SIN(Distance * .036 * PI# / 180), -13 * COS(Distance * .036 * PI# / 180)), 3 LOCATE 24, 58 PRINT "Distance"; ' Rate of Climb Indicator LINE (550, 190)-(630, 270), 0, BF CIRCLE (590, 230), 40 LINE (590, 190)-(590, 200) LINE (550, 230)-(560, 230) LINE (620, 230)-(630, 230) LINE (590, 260)-(590, 270) LINE (590, 230)-STEP(39 * SIN(PI# / 2 - Velocity.Y * 36 * PI# / 180), -39 * COS(PI# / 2 - Velocity.Y * 36 * PI# / 180)), 3 LINE (590, 230)-STEP(29 * SIN(PI# / 2 - Velocity.Y * 3.6 * PI# / 180), -29 * COS(PI# / 2 - Velocity.Y * 3.6 * PI# / 180)), 3 LINE (590, 230)-STEP(19 * SIN(PI# / 2 - Velocity.Y * .36 * PI# / 180), -19 * COS(PI# / 2 - Velocity.Y * .36 * PI# / 180)), 3 LOCATE 18, 70 PRINT "Climb Rate"; ' Speedometer LINE (450, 190)-(530, 270), 0, BF CIRCLE (490, 230), 40 LINE (490, 190)-(490, 200) LINE (450, 230)-(460, 230) LINE (520, 230)-(530, 230) LINE (490, 260)-(490, 270) LINE (490, 230)-STEP(39 * SIN(Velocity.X * 36 * PI# / 180), -39 * COS(Velocity.X * 36 * PI# / 180)), 3 LINE (490, 230)-STEP(29 * SIN(Velocity.X * 3.6 * PI# / 180), -29 * COS(Velocity.X * 3.6 * PI# / 180)), 3 LINE (490, 230)-STEP(19 * SIN(Velocity.X * .36 * PI# / 180), -19 * COS(Velocity.X * .36 * PI# / 180)), 3 LINE (490, 230)-STEP(13 * SIN(Velocity.X * .036 * PI# / 180), -13 * COS(Velocity.X * .036 * PI# / 180)), 3 LOCATE 18, 58 PRINT "Grnd Speed"; IF Altitude < 0 THEN GOSUB surface LOCATE 1, 1 PRINT " Thr(x): "; PRINT USING "####.###"; Thrust.X; PRINT " "; PRINT " Thr(y): "; PRINT USING "####.###"; Thrust.Y PRINT " Drag(x):"; PRINT USING "####.###"; Drag.X; PRINT " "; PRINT " Drag(y): "; PRINT USING "####.###"; Drag.Y PRINT " A(x): "; PRINT USING "####.###"; Accel.X; PRINT " "; PRINT " A(y): "; PRINT USING "####.###"; Accel.Y PRINT " V(x): "; PRINT USING "####.###"; Velocity.X; PRINT " "; PRINT " V(y): "; PRINT USING "####.###"; Velocity.Y PRINT " Dist: "; PRINT USING "####.###"; Distance; PRINT " "; PRINT " Alt: "; PRINT USING "####.###"; Altitude PRINT " Thrust: "; PRINT USING "####.###"; Thrust; PRINT " "; PRINT " Prop: "; PRINT USING "####.###"; Prop PRINT " Time: "; PRINT USING "####.###"; ET; PRINT " "; PRINT "Throttle: "; PRINT USING "###.###"; Throttle WEND surface: IF SQR(Velocity.X ^ 2 + Velocity.Y ^ 2) > 20 THEN GOSUB crashdead ELSEIF SQR(Velocity.X ^ 2 + Velocity.Y ^ 2) > 10 THEN GOSUB crashhurt ELSEIF SQR(Velocity.X ^ 2 + Velocity.Y ^ 2) > 5 THEN GOSUB crashwalk ELSEIF SQR(Velocity.X ^ 2 + Velocity.Y ^ 2) > 2 THEN GOSUB hardland ELSEIF SQR(Velocity.X ^ 2 + Velocity.Y ^ 2) <= 2 THEN GOSUB softland END IF INPUT ; "Would you like to play again? ", PlayAgain$ IF UCASE$(MID$(PlayAgain$, 1, 1)) = "Y" THEN ET = 0 Throttle = 50 Axis.Theta.Absolute = 0 YawRate = 0 Thrust.X = 0 Thrust.Y = 0 Accel.X = 0 Accel.Y = 0 Velocity.X = 0 Velocity.Y = 0 Altitude = 0 Distance = 0 Thrust = 0 Prop = 37.6 DW = 44.1 Isp = 1000 Engine.Out = 1111 GOTO SimStart ELSE END END IF RETURN crashdead: LOCATE 8, 1 PRINT "You have crashed at"; PRINT SQR(Velocity.X ^ 2 + Velocity.Y ^ 2); PRINT "meters per second. You are dead." SOUND 90, 9 DO WHILE INKEY$ = "" LOOP RETURN crashhurt: LOCATE 8, 1 PRINT "You have crashed at"; PRINT SQR(Velocity.X ^ 2 + Velocity.Y ^ 2); PRINT "meters per second. You are injured." SOUND 90, 9 DO WHILE INKEY$ = "" LOOP RETURN crashwalk: LOCATE 8, 1 PRINT "You have crash-landed at"; PRINT SQR(Velocity.X ^ 2 + Velocity.Y ^ 2); PRINT "meters per second." PRINT "Oh well, any landing you walk away from is a good landing." SOUND 90, 9 DO WHILE INKEY$ = "" LOOP RETURN hardland: LOCATE 8, 1 PRINT "You have landed hard at"; PRINT SQR(Velocity.X ^ 2 + Velocity.Y ^ 2); PRINT "meters per second. Your vehicle is crippled." SOUND 90, 9 DO WHILE INKEY$ = "" LOOP RETURN softland: LOCATE 8, 1 PRINT "You have soft landed at"; PRINT SQR(Velocity.X ^ 2 + Velocity.Y ^ 2); PRINT "meters per second. Congratulations!" IF Milestone(7) = 1 THEN Milestone(8) = 1 SOUND 900, 9 END IF DO WHILE INKEY$ = "" LOOP RETURN IncSimSpeed: TimeIncrement = TimeIncrement * 1.2 RETURN DecSimSpeed: TimeIncrement = TimeIncrement / 1.2 RETURN DecThrottle: Throttle = Throttle - 1 IF Throttle < 0 THEN Throttle = 0 RETURN IncThrottle: Throttle = Throttle + 1 IF Throttle > 100 THEN Throttle = 100 RETURN YawLeft: YawRate = YawRate - 1 RETURN YawRight: YawRate = YawRate + 1 RETURN