Advertisement
Drainedsoul

Milestone #3

Mar 5th, 2013
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 17.80 KB | None | 0 0
  1. #pragma config(Sensor,in1,right_quad,sensorQuadEncoder,int5)
  2. #pragma config(Sensor,in2,left_quad,sensorQuadEncoder,int6)
  3. #pragma config(Motor,port1,right_motor,tmotorNormal,openLoop)
  4. #pragma config(Motor,port2,left_motor,tmotorNormal,openLoop)
  5. #pragma config(Motor,port8,arm_motor,tmotorNormal,openLoop)
  6. #pragma config(Sensor,in3,right_button,sensorTouch)
  7. #pragma config(Sensor,in4,left_button,sensorTouch)
  8. #pragma config(Sensor,in5,arm_limit_switch,sensorTouch)
  9. //  Sensor and motor configuration
  10.  
  11.  
  12. /*
  13.  *  CONSTANTS
  14.  */
  15.  
  16.  
  17. //  QUEUE
  18.  
  19. //  Maximum number of motions in the queue
  20. #define QUEUE_SIZE 4
  21. //  Number of integers per element in the queue
  22. #define QUEUE_NUM_PER_ELEMENT 2
  23.  
  24.  
  25. //  MOTOR CONTROL
  26.  
  27. //  Maximum power level of a motor
  28. #define MOTOR_MAX 100
  29. //  Default power level of a motor
  30. #define MOTOR_ON MOTOR_MAX
  31. //  Off power level of a motor
  32. #define MOTOR_OFF 0
  33. //  Scalar that will be used to obtain
  34. //  the actual power level of the right
  35. //  motor
  36. #define RIGHT_SCALAR 1
  37. //  Scalar that will be used to obtain
  38. //  the actual power level of the left
  39. //  motor
  40. #define LEFT_SCALAR (-1)
  41. //  Braking power
  42. #define MOTOR_BRAKE 25
  43. //  Scalar for obtaining reverse power
  44. //  levels
  45. #define BACKWARDS_SCALAR (-1)
  46.  
  47.  
  48. //  BRAKING
  49.  
  50. //  The timer to use for brake polling
  51. #define BRAKE_TIMER T1
  52. //  The interval at which to poll while braking in milliseconds
  53. #define BRAKE_INTERVAL 50
  54.  
  55.  
  56. //  ADAPTIVE ANGULAR VELOCITY ALGORITHM
  57.  
  58. //  The timer to use for power adjustment polling
  59. #define TRIM_TIMER T1
  60. //  The interval at which to recalculate angular velocity
  61. //  and adjust power levels accordings in milliseconds
  62. #define TRIM_INTERVAL 100
  63. //  The amount a motor's power level will be stepped up
  64. //  or down each time it's found to be necessary
  65. #define TRIM_STEP 1
  66.  
  67.  
  68. //  ANGULAR ACCELERATION COLLISION DETECTION ALGORITHM
  69.  
  70. //  Minimum number of deltas needed to calculate acceleration
  71. #define MIN_DELTAS 2
  72. //  The number of subsequent times an axle must have a negative
  73. //  acceleration before a collision is detected
  74. #define COLLISION_THRESHOLD 5
  75.  
  76.  
  77. //  MOVEMENT PARAMETERS
  78.  
  79. //  Distance to move forwards in response
  80. //  to button push in millimeters
  81. #define FORWARD_DISTANCE 1000
  82. //  Distance to move backwards in response
  83. //  to button push in millimeters
  84. #define BACKWARD_DISTANCE 1000
  85.  
  86.  
  87. /*
  88.  *  MACROS
  89.  */
  90. #define LEFT_QUAD abs(SensorValue[left_quad])
  91. #define RIGHT_QUAD abs(SensorValue[right_quad])
  92.  
  93.  
  94. /*
  95.  *  TYPE DEFINITIONS/DECLARATIONS
  96.  */
  97.  
  98.  
  99. /*
  100.  *  Types of motions the robot
  101.  *  may execute
  102.  */
  103. typedef enum {
  104.  
  105.     Stopped,        //  Robot is not moving
  106.     TurnLeft,       //  Robot is turning left as part of a correction
  107.     TurnRight,      //  Robot is turning right as part of a correction
  108.     Straight,       //  Full speed ahead
  109.     Approach,       //  Ahead at low power
  110.     ScanLeft,       //  Robot is turning to the left, scanning
  111.     ScanRight,      //  Robot is turning to the right, scanning
  112.     CorrectLeft,    //  Robot is making a fine correction to the left
  113.     CorrectRight,   //  Robot is making a fine correction to the left
  114.     Retreat         //  Robot has encountered an obstacle and is backing off
  115.  
  116. } MotionType;
  117.  
  118.  
  119. /*
  120.  *  Encapsulates all information about
  121.  *  a motion.
  122.  */
  123. typedef struct {
  124.  
  125.     //  Type of motion
  126.     MotionType type;
  127.     //  How long the motion is to be executed for
  128.     int distance;
  129.  
  130. } Motion;
  131.  
  132.  
  133. /*
  134.  *  Encapsulates all information about
  135.  *  a motor.
  136.  */
  137. typedef struct {
  138.  
  139.     //  The maximum power level that this motor
  140.     //  may take on.  This is learned by observation
  141.     //  of the motors' angular velocity with respect
  142.     //  to the angular velocity of the opposing motor.
  143.     int max_power;
  144.     //  The current speed this motor is set to.  This
  145.     //  will be scaled by max_power so that speed=MOTOR_MAX
  146.     //  corresponds to max_power.
  147.     int power;
  148.     //  The motor's angular displacement as last measured.
  149.     int old;
  150.     //  The motor's angular velocity as last measured.
  151.     int delta;
  152.     //  The motor's angular acceleration as last measured.
  153.     int delta_delta;
  154.     //  The motor's last delta (used for acceleration
  155.     //  calculations).
  156.     int old_delta;
  157.     //  Whether the motor is being braked
  158.     bool brake;
  159.     //  The number of subsequent polls which have
  160.     //  detected a collision
  161.     int collision_count;
  162.  
  163. } MotorInfo;
  164.  
  165.  
  166. /*
  167.  *  GLOBALS
  168.  */
  169.  
  170.  
  171. //  QUEUE
  172.  
  173. int queue_mem [QUEUE_SIZE*QUEUE_NUM_PER_ELEMENT];
  174. int queue_begin;
  175. int queue_end;
  176.  
  177.  
  178. //  Information about the right motor
  179. MotorInfo right;
  180. //  Information about the left motor
  181. MotorInfo left;
  182. //  Information about the current motion
  183. Motion curr;
  184. //  How many times the delta of the motors
  185. //  has been recorded since this motion began.
  186. //
  187. //  Maximum value: 2.
  188. //  Default value: 0
  189. int num_deltas;
  190. //  Whether a push of the left button
  191. //  has had the corresponding event
  192. //  dispatched.
  193. //
  194. //  Default value: false
  195. bool left_push_handled;
  196. //  Whether a push of the right button
  197. //  has had the corresponding event
  198. //  dispatched.
  199. //
  200. //  Default value: true
  201. bool right_push_handled;
  202. //  Whether the robot is currently
  203. //  in the process of coming to stop
  204. //  after a motion completes.
  205. //
  206. //  Default value: false
  207. bool braking;
  208. //  Set if the robot should skip
  209. //  the current motion immediately.
  210. //
  211. //  Default value: false
  212. bool skip;
  213. /*
  214.  *  There are ~1.13599117689mm per degree
  215.  *  of rotation of the 5 1/8" wheels used
  216.  *  for the robot.
  217.  *
  218.  *  Since the VEX PIC 0.5 doesn't support
  219.  *  floating point arithmetic, if we simply
  220.  *  rounded this number to the nearest integer
  221.  *  we would be ~15% under -- a large margin.
  222.  *
  223.  *  However, multiplying by arbitrary powers
  224.  *  of ten to "push" decimals into whole numbers
  225.  *  and thereby increase the precision is also
  226.  *  not an option, due to the extremely limited
  227.  *  (-32 768 to 32 767) 16-bit signed (unsigned
  228.  *  integers also unsupported mysteriously) range
  229.  *  of integers on the VEX PIC 0.5.
  230.  *
  231.  *  Therefore we have the variable "periods" and
  232.  *  the variable "nums" which are arrays of const
  233.  *  integers.  "periods" specifies the number of
  234.  *  degrees after which a component of the
  235.  *  floating point number given above shall
  236.  *  "accumulate" into some whole number of millimeters.
  237.  *  "nums" specifies the number of whole millimeters that
  238.  *  shall be accumulated after the specified period.
  239.  */
  240. const int periods []={
  241.     1,      //  Ones                (1*1)/      1
  242.             //                                  .
  243.     10,     //  Tens                (1*10)/     1
  244.     100,    //  Hundreds            (3*100)/    3
  245.     500     //  Thousands           (3*1000)/   6   Rounded off here
  246.             //                                  .
  247.             //                                  .
  248.             //                                  .
  249. };
  250. const int nums []={
  251.     1,
  252.     1,
  253.     3,
  254.     3
  255. };
  256. #define NUM_ACCUMULATE 4
  257.  
  258.  
  259. /*
  260.  *  FUNCTIONS
  261.  */
  262.  
  263.  
  264. /*
  265.  *  Prepares the queue for use.
  266.  */
  267. void init_queue () {
  268.  
  269.     queue_begin=0;
  270.     queue_end=0;
  271.  
  272. }
  273.  
  274.  
  275. /*
  276.  *  Enqueues a new motion, if possible.
  277.  *
  278.  *  Returns false if the motion could not
  279.  *  be enqueued.
  280.  */
  281. bool enqueue (MotionType type, int distance) {
  282.  
  283.     //  Bounds check
  284.     if (queue_end==(QUEUE_SIZE*QUEUE_NUM_PER_ELEMENT)) return false;
  285.    
  286.     //  Enqueue
  287.     queue_mem[queue_end]=(int)type;
  288.     ++queue_end;
  289.     queue_mem[queue_end]=distance;
  290.     ++queue_end;
  291.    
  292.     //  Succeed
  293.     return true;
  294.  
  295. }
  296.  
  297.  
  298. /*
  299.  *  Attempts to dequeue a motion from the
  300.  *  queue and store it in the global "curr".
  301.  *
  302.  *  Returns false if there are no motions
  303.  *  to dequeue.
  304.  */
  305. bool dequeue () {
  306.  
  307.     //  Bounds check
  308.     if (queue_end==queue_begin) return false;
  309.    
  310.     //  Dequeue
  311.     curr.type=(MotionType)queue_mem[queue_begin];
  312.     ++queue_begin;
  313.     curr.distance=queue_mem[queue_begin];
  314.     ++queue_begin;
  315.    
  316.     //  Reset pointers to the beginning
  317.     //  to reuse memory
  318.     if (queue_end==queue_begin) {
  319.    
  320.         queue_end=0;
  321.         queue_begin=0;
  322.    
  323.     }
  324.    
  325.     //  Succeed
  326.     return true;
  327.  
  328. }
  329.  
  330.  
  331. /*
  332.  *  Clears all motions from the queue.
  333.  */
  334. void clear_queue () {
  335.  
  336.     queue_end=0;
  337.     queue_begin=0;
  338.  
  339. }
  340.  
  341.  
  342. /*
  343.  *  Retrieves a count of the number
  344.  *  of motions in the queue.
  345.  */
  346. int count_queue () {
  347.  
  348.     return (queue_end-queue_begin)/QUEUE_NUM_PER_ELEMENT;
  349.  
  350. }
  351.  
  352.  
  353. /*
  354.  *  Resets all applicable values
  355.  *  after the completion or abortion
  356.  *  of a motion.
  357.  */
  358. void motion_reset () {
  359.  
  360.     right.old=0;
  361.     left.old=0;
  362.    
  363.     right.collision_count=0;
  364.     left.collision_count=0;
  365.    
  366.     SensorValue[right_quad]=0;
  367.     SensorValue[left_quad]=0;
  368.    
  369.     num_deltas=0;
  370.    
  371.     ClearTimer(TRIM_TIMER);
  372.  
  373. }
  374.  
  375.  
  376. /*
  377.  *  Commits all changes to speeds
  378.  *  to the motors.
  379.  */
  380. void motors_commit () {
  381.  
  382.     motor[right_motor]=RIGHT_SCALAR*((right.max_power*right.power)/MOTOR_MAX);
  383.     motor[left_motor]=LEFT_SCALAR*((left.max_power*left.power)/MOTOR_MAX);
  384.  
  385. }
  386.  
  387.  
  388. /*
  389.  *  Polls the quadrature encoders
  390.  *  and thereby obtains information
  391.  *  about the angular displacement,
  392.  *  velocity, and acceleration
  393.  *  of the axles.
  394.  *
  395.  *  Using this information the motors'
  396.  *  power levels are evened out such
  397.  *  that the robot goes straight, and
  398.  *  collisions are detected (when a
  399.  *  gross negative angular acceleration
  400.  *  occurs).
  401.  */
  402. void motor_maintenance () {
  403.  
  404.     //  Only execute at each expiration
  405.     //  of the polling interval
  406.     if (time1[TRIM_TIMER]>=TRIM_INTERVAL) {
  407.    
  408.         //  Reset timer for next poll
  409.         ClearTimer(TRIM_TIMER);
  410.        
  411.         //  Acquire and calculate values
  412.        
  413.         int new_right=RIGHT_QUAD;
  414.         int new_left=LEFT_QUAD;
  415.        
  416.         //  Increment delta counter if
  417.         //  it's low enough (i.e. under 2)
  418.         //  that it would be meaningful
  419.         if (num_deltas<MIN_DELTAS) ++num_deltas;
  420.        
  421.         //  Store previous velocities
  422.         right.old_delta=right.delta;
  423.         left.old_delta=left.delta;
  424.        
  425.         //  Calculate angular velocities
  426.         left.delta=abs(new_left-left.old);
  427.         right.delta=abs(new_right-right.old);
  428.        
  429.         right.old=new_right;
  430.         left.old=new_left;
  431.        
  432.         //  Right wheel is spinning faster
  433.         if (right.delta>left.delta) {
  434.        
  435.             //  Adjust power of left wheel up
  436.             //  unless it's already at maximum
  437.             //  power, in which case decrease
  438.             //  the power of the right wheel,
  439.             //  unless it's turned off
  440.            
  441.             if (left.max_power!=MOTOR_MAX) left.max_power+=TRIM_STEP;
  442.             else if (right.max_power!=MOTOR_OFF) right.max_power-=TRIM_STEP;
  443.        
  444.         //  Left wheel is spinning faster
  445.         } else if (left.delta>right.delta) {
  446.        
  447.             //  Adjust power of right wheel up
  448.             //  unless it's already at maximum
  449.             //  power, in which case decrease
  450.             //  the power of the left wheel,
  451.             //  unless it's turned off
  452.             if (right.max_power!=MOTOR_MAX) right.max_power+=TRIM_STEP;
  453.             else if (left.max_power!=MOTOR_OFF) left.max_power-=TRIM_STEP;
  454.        
  455.         }
  456.        
  457.         //  If we have at least two deltas
  458.         //  we can calculate the angular
  459.         //  acceleration
  460.         if (num_deltas>=MIN_DELTAS) {
  461.        
  462.             //  Calculate angular acceleration
  463.             right.delta_delta=right.delta-right.old_delta;
  464.             left.delta_delta=left.delta-left.old_delta;
  465.            
  466.             //  Has either axle inexplicably stopped completely?
  467.             //  If so trigger a collision straight away
  468.             if (
  469.                 //  Right axle
  470.                 (
  471.                     (right.power!=0) &&
  472.                     (right.delta==0)
  473.                 ) ||
  474.                 //  Left axle
  475.                 (
  476.                     (left.power!=0) &&
  477.                     (left.delta==0)
  478.                 )
  479.             ) goto collision;
  480.            
  481.             //  Check for negative angular acceleration on
  482.             //  the right axle
  483.             if (
  484.                 (right.power!=0) &&
  485.                 (right.delta_delta<0)
  486.             ) ++right.collision_count;
  487.             else right.collision_count=0;
  488.            
  489.             //  Check for negative angular acceleration on
  490.             //  the left axle
  491.             if (
  492.                 (left.power!=0) &&
  493.                 (left.delta_delta<0)
  494.             ) ++left.collision_count;
  495.             else left.collision_count=0;
  496.            
  497.             //  See if either collision count is over the threshold
  498.             if (
  499.                 (left.collision_count>=COLLISION_THRESHOLD) ||
  500.                 (right.collision_count>=COLLISION_THRESHOLD)
  501.             ) {
  502.            
  503.                 //  Entry from above
  504.                 collision:
  505.                
  506.                 for (;;) {
  507.                
  508.                     motor[right_motor]=MOTOR_OFF;
  509.                     motor[left_motor]=MOTOR_OFF;
  510.                
  511.                 }
  512.            
  513.             }
  514.        
  515.         }
  516.    
  517.     }
  518.  
  519. }
  520.  
  521.  
  522. /*
  523.  *  Ends a motion by bringing
  524.  *  the robot to a stop as
  525.  *  quickly as possible.
  526.  */
  527. void brake () {
  528.  
  529.     //  If both motors are powered
  530.     //  down and we're not braking,
  531.     //  pass
  532.     if (
  533.         (right.power==MOTOR_OFF) &&
  534.         (left.power==MOTOR_OFF) &&
  535.         !braking
  536.     ) return;
  537.    
  538.     //  If we weren't already braking
  539.     //  get setup
  540.     if (!braking) {
  541.    
  542.         //  Set defaults
  543.         right.brake=false;
  544.         left.brake=false;
  545.        
  546.         //  If the left motor is running, brake it
  547.         if (left.power!=MOTOR_OFF) {
  548.        
  549.             left.brake=true;
  550.            
  551.             //  Set braking power in the opposite direction
  552.             left.power=
  553.                 //  Obtains the sign of the current power
  554.                 (left.power/abs(left.power))*
  555.                 //  Reverses it
  556.                 BACKWARDS_SCALAR*
  557.                 //  Scales it up to braking power
  558.                 MOTOR_BRAKE;
  559.        
  560.         }
  561.        
  562.         //  If the right motor is running, brake it
  563.         if (right.power!=MOTOR_OFF) {
  564.        
  565.             right.brake=true;
  566.            
  567.             //  Set braking power in the opposite direction
  568.             right.power=
  569.                 //  Obtains the sign of the current power
  570.                 (right.power/abs(right.power))*
  571.                 //  Reverses it
  572.                 BACKWARDS_SCALAR*
  573.                 //  Scales it up to braking power
  574.                 MOTOR_BRAKE;
  575.        
  576.         }
  577.        
  578.         //  We are now braking
  579.         braking=true;
  580.        
  581.         //  Reset the poll timer
  582.         ClearTimer(BRAKE_TIMER);
  583.        
  584.         //  We use raw quad values because
  585.         //  sign matters
  586.         right.old=SensorValue[right_quad];
  587.         left.old=SensorValue[left_quad];
  588.    
  589.     }
  590.    
  591.     //  Pass until it's time to poll
  592.     if (time1[BRAKE_TIMER]<BRAKE_INTERVAL) return;
  593.    
  594.     //  Begin next poll interval
  595.     ClearTimer(BRAKE_TIMER);
  596.    
  597.     //  Calculate deltas
  598.     right.delta=SensorValue[right_quad]-right.old;
  599.     left.delta=SensorValue[left_quad]-left.old;
  600.    
  601.     //  Update values
  602.     right.old=SensorValue[right_quad];
  603.     left.old=SensorValue[left_quad];
  604.    
  605.     //  Check right axle
  606.     if (right.brake) {
  607.        
  608.         if (
  609.             //  Axle has completely stopped
  610.             (right.delta==0) ||
  611.             (
  612.                 //  Avoid divide by zero
  613.                 (right.old!=0) &&
  614.                 //  Motor moved just slightly in the opposite
  615.                 //  direction (we're just comparing the signs)
  616.                 ((right.delta/abs(right.delta))!=(right.old/abs(right.old)))
  617.             )
  618.         ) {
  619.        
  620.             //  Power down
  621.             right.power=MOTOR_OFF;
  622.        
  623.         }
  624.    
  625.     }
  626.    
  627.     //  Check left axle
  628.     if (left.brake) {
  629.        
  630.         if (
  631.             //  Axle has completely stopped
  632.             (left.delta==0) ||
  633.             (
  634.                 //  Avoid divide by zero
  635.                 (left.old!=0) &&
  636.                 //  Axle moved just slightly in the opposite
  637.                 //  direction (we're just comparing the signs)
  638.                 ((left.delta/abs(left.delta))!=(left.old/abs(left.old)))
  639.             )
  640.         ) {
  641.        
  642.             //  Power down
  643.             left.power=MOTOR_OFF;
  644.        
  645.         }
  646.    
  647.     }
  648.    
  649.     //  If both axles have completely stopped
  650.     //  moving, braking is over
  651.     if (
  652.         (right.delta==0) &&
  653.         (left.delta==0)
  654.     ) braking=false;
  655.  
  656. }
  657.  
  658.  
  659. /*
  660.  *  Returns an approximation of the
  661.  *  distance the robot has travelled
  662.  *  since the last time the quadrature
  663.  *  encoders were reset.
  664.  *
  665.  *  Picks whichever quad encoder has
  666.  *  logged the most angular displacement
  667.  *  and performs simulated floating point
  668.  *  multiplication to convert that
  669.  *  angular displacement into linear
  670.  *  displacement.
  671.  */
  672. int distance_travelled () {
  673.  
  674.     int left_quad_val=LEFT_QUAD;
  675.     int right_quad_val=RIGHT_QUAD;
  676.    
  677.     int quad_val=(left_quad_val<right_quad_val) ? right_quad_val : left_quad_val;
  678.    
  679.     int returnthis=0;
  680.    
  681.     int i;
  682.     for (i=0;i<NUM_ACCUMULATE;++i) returnthis+=(quad_val/periods[i])*nums[i];
  683.    
  684.     return returnthis;
  685.  
  686. }
  687.  
  688.  
  689. /*
  690.  *  Maintains the robot's motion.
  691.  */
  692. void movement () {
  693.  
  694.     //  If braking is in function call
  695.     //  the braking function
  696.     if (braking) {
  697.    
  698.         brake();
  699.        
  700.         //  If braking just ended
  701.         //  reset
  702.         if (!braking) motion_reset();
  703.        
  704.     }
  705.    
  706.     //  If we're braking, pass
  707.     if (!braking) {
  708.    
  709.         //  Whether a new movement has just begun
  710.         bool new_movement=false;
  711.    
  712.         //  If the robot is currently stopped
  713.         //  or if we're skipping the remainder of
  714.         //  this motion or if this motion is
  715.         //  complete, check for a new motion.
  716.         if (
  717.             (curr.type==Stopped) ||
  718.             (distance_travelled()>=curr.distance)
  719.         ) {
  720.        
  721.             new_movement=dequeue();
  722.            
  723.             if (!new_movement) curr.type=Stopped;
  724.        
  725.         }
  726.        
  727.         //  Reset skip so we don't skip
  728.         //  subsequent motions
  729.         skip=false;
  730.        
  731.         //  If we're stopped, stopping, or
  732.         //  transitioning call the brake
  733.         //  function and keep everything reset
  734.         if (
  735.             (curr.type==Stopped) ||
  736.             new_movement
  737.         ) {
  738.        
  739.             //  THE ORDER IN WHICH THESE ARE CALLED IS
  740.             //  VERY SIGNIFICANT DO NOT REARRANGE
  741.             motion_reset();
  742.             ClearTimer(TRIM_TIMER);
  743.             brake();
  744.        
  745.         //  Otherwise perform movement maintenance
  746.         } else {
  747.        
  748.             //  Set speeds for the various motions
  749.             switch (curr.type) {
  750.            
  751.                 //  Straight ahead
  752.                 case Straight:{
  753.                
  754.                     right.power=MOTOR_ON;
  755.                     left.power=MOTOR_ON;
  756.                
  757.                 }break;
  758.                
  759.                 //  Reverse
  760.                 case Retreat:{
  761.                
  762.                     right.power=BACKWARDS_SCALAR*MOTOR_ON;
  763.                     left.power=BACKWARDS_SCALAR*MOTOR_ON;
  764.                
  765.                 }break;
  766.            
  767.             }
  768.        
  769.         }
  770.        
  771.         motor_maintenance();
  772.    
  773.     }
  774.    
  775.     //  Commit power changes
  776.     motors_commit();
  777.  
  778. }
  779.  
  780.  
  781. /*
  782.  *  Monitors inputs and takes appropriate
  783.  *  action.
  784.  */
  785. void monitor_input () {
  786.  
  787.     //  LEFT BUTTON
  788.    
  789.     //  If the button has been released
  790.     //  the next event will be handled
  791.     if (SensorValue[left_button]==0) {
  792.    
  793.         left_push_handled=false;
  794.    
  795.     //  If the button is pressed and
  796.     //  we can handle the event, do so
  797.     } else if (!left_push_handled) {
  798.    
  799.         //  Block this event from being
  800.         //  handled on subsequent
  801.         //  invocations
  802.         left_push_handled=true;
  803.        
  804.         enqueue(Straight,FORWARD_DISTANCE);
  805.    
  806.     }
  807.    
  808.     //  RIGHT BUTTON
  809.    
  810.     //  If the button has been released
  811.     //  the next event will be handled
  812.     if (SensorValue[right_button]==0) {
  813.    
  814.         right_push_handled=false;
  815.    
  816.     //  If the button is pressed and
  817.     //  we can handle the event, do so
  818.     } else if (!right_push_handled) {
  819.    
  820.         //  Block this event from being
  821.         //  handled on subsequent
  822.         //  invocations
  823.         right_push_handled=true;
  824.        
  825.         enqueue(Retreat,BACKWARD_DISTANCE);
  826.    
  827.     }
  828.  
  829. }
  830.  
  831.  
  832. /*
  833.  *  MAIN
  834.  */
  835.  
  836.  
  837. task main () {
  838.  
  839.     //  Initialize and fulfill pre-conditions
  840.     init_queue();
  841.     motion_reset();
  842.     right.max_power=MOTOR_MAX;
  843.     left.max_power=MOTOR_MAX;
  844.     right.power=MOTOR_OFF;
  845.     left.power=MOTOR_OFF;
  846.     curr.type=Stopped;
  847.     left_push_handled=false;
  848.     right_push_handled=false;
  849.     braking=false;
  850.     skip=false;
  851.     motors_commit();
  852.    
  853.     //  Loop forever
  854.     for (;;) {
  855.    
  856.         monitor_input();
  857.         movement();
  858.    
  859.     }
  860.  
  861. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement