26 #define MOTOR_POWER_FAST 100
27 #define MOTOR_POWER_MODERATE 75
28 #define MOTOR_POWER_SLOW 30
36 #define MOTOR_TILT OUT_C
37 #define MOTOR_STRIDE OUT_B
38 #define MOTOR_NECK OUT_A
40 #define NECK_CYCLE 2160
43 #define TOUCH_SENSOR IN_1
44 #define SOUND_SENSOR IN_2
45 #define LIGHT_SENSOR IN_3
46 #define RANGE_SENSOR IN_4
49 #define TOUCH_SENSOR_OFFSET -25
50 #define LIGHT_SENSOR_OFFSET 12
53 #define SOUND_SENSOR_THRESHOLD 60
56 #define RANGE_SENSOR_THRESHOLD 50
59 #define LIGHT_SENSOR_PROXIMITY_THRESHOLD 40
62 #define CALIBERATION_ERROR_TOLERANCE 90
66 #define MOVE_FORWARD 1
69 #define NUM_COMMANDS 4
80 #define ACTION_ELEMENT_STRIDE_FIRST 0
81 #define ACTION_ELEMENT_TILT_AMOUNT 1
82 #define ACTION_ELEMENT_STRIDE_AMOUNT 2
83 #define NUM_ELEMENTS 3
86 #define GetActionElement(int prevState, int nextState, int element) \
87 stateTransitionAction[prevState * NUM_STATES * NUM_ELEMENTS \
88 + nextState * NUM_ELEMENTS \
92 int stateTransitionAction[] = {
97 0, 0, 0, 0,-25, 50, 1,-25, 25, 0,-25, 0, 0,-50, 50,
98 0, 25,-50, 0, 0, 0, 0, 0,-25, 0, 0,-50, 0,-25, 0,
99 0, 25,-25, 0, 0, 25, 0, 0, 0, 0, 0,-25, 0,-25, 25,
100 0, 25, 0, 0, 0, 50, 0, 0, 25, 0, 0, 0, 0,-25, 50,
101 0, 50,-50, 0, 25, 0, 1, 25,-25, 0, 25,-50, 0, 0, 0,
106 int stateTransition[] = {
110 REST, RTLF, CLF, RTLF,
111 REST, LTRF, LTRF, RTLF,
112 REST, LTRF, LTRF, RTLF,
113 REST, LTRF, LTRF, RTLF,
114 REST, LTRF, LTRF, CRF,
119 int moveCommand = MOVE_STOP;
120 int moveState = REST;
121 int tiltCycleCount, strideCycleCount;
123 void startMotor(
int motor,
int power)
125 SetOutput(motor, OutputMode, OUT_MODE_MOTORON | OUT_MODE_BRAKE);
126 SetOutput(motor, Power, power);
127 SetOutput(motor, UpdateFlags, UF_UPDATE_MODE | UF_UPDATE_SPEED |
128 UF_UPDATE_RESET_BLOCK_COUNT);
129 SetOutput(motor, RunState, OUT_RUNSTATE_RUNNING);
132 void stopMotor(
int motor)
134 SetOutput(motor, RunState, OUT_RUNSTATE_IDLE);
135 SetOutput(motor, OutputMode, 0);
136 SetOutput(motor, Power, 0);
137 SetOutput(motor, UpdateFlags, UF_UPDATE_SPEED);
140 int RotateAngle(
int motor,
int power,
int angle,
int PValue,
int IValue,
int DValue)
143 int samplePeriod = 20;
148 int steadyStateCount = 0;
151 startMotor(motor, 0);
153 while(steadyStateCount < 5)
155 int absPower = Abs(power);
156 int error = angle - GetOutput(motor, BlockTachoCount);
159 if ((error - lastError) == 0)
162 int P = PValue * error / pidScale;
163 I += IValue * error * dt / pidScale;
164 int D = (DValue / dt) * (error - lastError) / pidScale;
165 int output = outputScale * (P + I + D);
166 if (output > absPower) output = absPower;
167 if (output < -absPower) output = -absPower;
168 SetOutput(motor, Power, output);
169 SetOutput(motor, UpdateFlags, UF_UPDATE_SPEED);
171 Wait(dt * samplePeriod);
177 int GetSensorProximity (
int sensor)
179 if (sensor == TOUCH_SENSOR)
180 return Sensor(TOUCH_SENSOR);
181 if (Sensor(LIGHT_SENSOR) < LIGHT_SENSOR_PROXIMITY_THRESHOLD)
187 int CaliberateMotor(
int motor,
int sensor,
int postAlignmentPercentage)
197 startMotor(motor, MOTOR_POWER_FAST);
200 while (GetSensorProximity(sensor));
203 while (!GetSensorProximity(sensor));
206 extremeTachoMin = GetOutput(motor, TachoCount);
207 cycleCountMin = extremeTachoMin;
210 while (GetSensorProximity(sensor));
213 extremeTachoMax = GetOutput(motor, TachoCount);
216 while (!GetSensorProximity(sensor));
219 cycleCountMax = GetOutput(motor, TachoCount);
225 cycleCount = cycleCountMax - cycleCountMin;
226 int errorCycleCount = cycleCount % CALIBERATION_ERROR_TOLERANCE;
227 if (errorCycleCount < CALIBERATION_ERROR_TOLERANCE/2)
228 cycleCount -= errorCycleCount;
230 cycleCount += CALIBERATION_ERROR_TOLERANCE - errorCycleCount;
234 alignDegrees = (cycleCount * postAlignmentPercentage)/100 +
235 (extremeTachoMax - extremeTachoMin)/2;
236 RotateAngle(motor, MOTOR_POWER_FAST, alignDegrees, MOTOR_P, MOTOR_I, MOTOR_D);
245 int command = moveCommand;
246 int nextState = stateTransition[moveState * NUM_COMMANDS + command];
250 int strideFirst = GetActionElement(moveState, nextState,
251 ACTION_ELEMENT_STRIDE_FIRST);
252 int tiltFraction = GetActionElement(moveState, nextState,
253 ACTION_ELEMENT_TILT_AMOUNT);
254 int strideFraction = GetActionElement(moveState, nextState,
255 ACTION_ELEMENT_STRIDE_AMOUNT);
257 if (tiltFraction && !strideFirst)
258 RotateAngle(MOTOR_TILT, MOTOR_POWER_FAST,
259 (tiltCycleCount * tiltFraction)/100,
260 MOTOR_P, MOTOR_I, MOTOR_D);
262 RotateAngle(MOTOR_STRIDE, MOTOR_POWER_FAST,
263 (strideCycleCount * strideFraction)/100,
264 MOTOR_P, MOTOR_I, MOTOR_D);
265 if (tiltFraction && strideFirst)
266 RotateAngle(MOTOR_TILT, MOTOR_POWER_FAST,
267 (tiltCycleCount * tiltFraction)/100,
268 MOTOR_P, MOTOR_I, MOTOR_D);
269 if (moveState == nextState)
271 moveState = nextState;
280 if(SensorUS(RANGE_SENSOR) < RANGE_SENSOR_THRESHOLD)
283 if (moveCommand == MOVE_FORWARD)
285 moveCommand = MOVE_LEFT;
292 if (moveCommand == MOVE_LEFT)
294 moveCommand = MOVE_FORWARD;
305 while(Sensor(SOUND_SENSOR) < SOUND_SENSOR_THRESHOLD) Wait(20);
307 if (moveCommand == MOVE_STOP)
309 moveCommand = MOVE_FORWARD;
313 moveCommand = MOVE_STOP;
322 SetSensorTouch(TOUCH_SENSOR);
323 SetSensorLight(LIGHT_SENSOR);
324 SetSensorSound(SOUND_SENSOR);
325 SetSensorLowspeed(RANGE_SENSOR);
335 RotateAngle(MOTOR_STRIDE, MOTOR_POWER_FAST,
336 strideCycleCount * (LIGHT_SENSOR_OFFSET)/100,
337 MOTOR_P, MOTOR_I, MOTOR_D);
338 RotateAngle(MOTOR_TILT, MOTOR_POWER_FAST,
339 tiltCycleCount * (TOUCH_SENSOR_OFFSET)/100,
340 MOTOR_P, MOTOR_I, MOTOR_D);
int CaliberateMotor(int motor, int sensor, int postAlignmentPercentage)
Caliberates a rotary motor setup that has a sensor attached to detect a cyclic position.