module lego1 : input TOUCH_1, TOUCH_3; output MOTOR_A_SPEED(integer), MOTOR_C_SPEED(integer), MOTOR_A_DIR(integer), MOTOR_C_DIR(integer), CPUTS(string); relation TOUCH_1 # TOUCH_3; sensor LIGHT_2_VALUE : integer; constant MOTOR_FWD, MOTOR_REV, MAX_SPEED : integer; signal RECOVERY_START, RECOVERY_END, RECOVERING in % This is the code to recover from bumping. var t : integer in % emit MOTOR_A_SPEED(MAX_SPEED/2); % emit MOTOR_C_SPEED(MAX_SPEED/2); every [TOUCH_1 or TOUCH_3] do % emit MOTOR_A_DIR(MOTOR_FWD); % emit MOTOR_C_DIR(MOTOR_FWD); % emit CPUTS("bump"); emit RECOVERY_START; present TOUCH_1 then t:=1; else t:=3; end present; emit MOTOR_A_DIR(MOTOR_REV); emit MOTOR_C_DIR(MOTOR_REV); await 100 tick; % 1 tick = 1 ms if t=1 then emit MOTOR_A_DIR(MOTOR_FWD); else emit MOTOR_C_DIR(MOTOR_FWD); end if; await 100 tick; % 1 tick = 1 ms % Go forward again emit MOTOR_A_DIR(MOTOR_FWD); emit MOTOR_C_DIR(MOTOR_FWD); emit CPUTS ("ok"); % and say that we have finished the recovery emit RECOVERY_END end every end var || % This is the code that generates the singnal RECOVERING. every RECOVERY_START do abort sustain RECOVERING when RECOVERY_END end every || % This is the main code, that seeks the light. suspend emit MOTOR_A_SPEED(MAX_SPEED/2); emit MOTOR_C_SPEED(MAX_SPEED/2); loop var light_l: integer, light_r: integer, light_c: integer, max_light: integer in % % Samples light % % Samples light in the center. light_c := ?LIGHT_2_VALUE; % Samples light on the left. emit MOTOR_A_DIR(MOTOR_REV); emit MOTOR_C_DIR(MOTOR_FWD); await 50 tick; light_l := ?LIGHT_2_VALUE; % Samples light on the right emit MOTOR_A_DIR(MOTOR_FWD); emit MOTOR_C_DIR(MOTOR_REV); await 100 tick; light_r := ?LIGHT_2_VALUE; % % Decides where to go % % Computes max light max_light := 0; if light_r > max_light then max_light := light_r end if; if light_l > max_light then max_light := light_l end if; if light_c > max_light then max_light := light_c end if; % Chooses the max light, giving preference to % going straight. if light_c = max_light then % goes straight emit CPUTS("strgt"); emit MOTOR_A_DIR(MOTOR_REV); emit MOTOR_C_DIR(MOTOR_FWD); await 50 tick; emit MOTOR_A_DIR(MOTOR_FWD); emit MOTOR_C_DIR(MOTOR_FWD); elsif light_r = max_light then % goes right, that is, straight from % current orientation. emit CPUTS("rght"); emit MOTOR_A_DIR(MOTOR_FWD); emit MOTOR_C_DIR(MOTOR_FWD); else % goes left emit CPUTS("left"); emit MOTOR_A_DIR(MOTOR_REV); emit MOTOR_C_DIR(MOTOR_FWD); await 100 tick; emit MOTOR_A_DIR(MOTOR_FWD); emit MOTOR_C_DIR(MOTOR_FWD); end if; % % Now goes straight for a while. % await 400 tick end var end loop when immediate RECOVERING end signal.