2 |
2 |
|
3 |
3 |
#include "global.hpp"
|
4 |
4 |
|
|
5 |
#include "linefollow2.hpp"
|
|
6 |
|
5 |
7 |
using namespace amiro;
|
6 |
8 |
|
7 |
9 |
extern Global global;
|
... | ... | |
55 |
57 |
int policyCounter = 0; // Do not change this, it points to the beginning of the policy
|
56 |
58 |
|
57 |
59 |
// Different speed settings (all values in "rounds per minute")
|
58 |
|
const int rpmForward[2] = {25,25};
|
59 |
|
const int rpmSoftLeft[2] = {15,25};
|
60 |
|
const int rpmHardLeft[2] = {10,25};
|
61 |
|
const int rpmSoftRight[2] = {rpmSoftLeft[1],rpmSoftLeft[0]};
|
62 |
|
const int rpmHardRight[2] = {rpmHardLeft[1],rpmHardLeft[0]};
|
63 |
60 |
const int rpmTurnLeft[2] = {-10, 10};
|
64 |
61 |
const int rpmTurnRight[2] = {rpmTurnLeft[1],rpmTurnLeft[0]};
|
65 |
62 |
const int rpmHalt[2] = {0, 0};
|
... | ... | |
111 |
108 |
void copyRpmSpeed(const int (&source)[2], int (&target)[2]) {
|
112 |
109 |
target[constants::DiWheelDrive::LEFT_WHEEL] = source[constants::DiWheelDrive::LEFT_WHEEL];
|
113 |
110 |
target[constants::DiWheelDrive::RIGHT_WHEEL] = source[constants::DiWheelDrive::RIGHT_WHEEL];
|
|
111 |
chprintf((BaseSequentialStream*) &SD1, "Speed left: %d, Speed right: %d\r\n", target[0], target[1]);
|
114 |
112 |
}
|
115 |
113 |
|
116 |
114 |
// Fuzzyfication of the sensor values
|
... | ... | |
198 |
196 |
} else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == BLACK &&
|
199 |
197 |
member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == BLACK) {
|
200 |
198 |
// straight
|
201 |
|
copyRpmSpeed(rpmForward, rpmFuzzyCtrl);
|
|
199 |
copyRpmSpeed(global.rpmForward, rpmFuzzyCtrl);
|
202 |
200 |
// exact one front sensor detects a line
|
203 |
201 |
} else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == BLACK ||
|
204 |
202 |
member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == BLACK) {
|
205 |
203 |
// soft correction
|
206 |
204 |
if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == GREY) {
|
207 |
205 |
// soft right
|
208 |
|
copyRpmSpeed(rpmSoftRight, rpmFuzzyCtrl);
|
|
206 |
copyRpmSpeed(global.rpmSoftRight, rpmFuzzyCtrl);
|
209 |
207 |
} else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == WHITE) {
|
210 |
208 |
// hard right
|
211 |
|
copyRpmSpeed(rpmHardRight, rpmFuzzyCtrl);
|
|
209 |
copyRpmSpeed(global.rpmHardRight, rpmFuzzyCtrl);
|
212 |
210 |
} else if (member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == GREY) {
|
213 |
211 |
// soft left
|
214 |
|
copyRpmSpeed(rpmSoftLeft, rpmFuzzyCtrl);
|
|
212 |
copyRpmSpeed(global.rpmSoftLeft, rpmFuzzyCtrl);
|
215 |
213 |
} else if (member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == WHITE) {
|
216 |
214 |
// hard left
|
217 |
|
copyRpmSpeed(rpmHardLeft, rpmFuzzyCtrl);
|
|
215 |
copyRpmSpeed(global.rpmHardLeft, rpmFuzzyCtrl);
|
218 |
216 |
}
|
219 |
217 |
// both wheel sensors detect a line
|
220 |
218 |
} else if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == BLACK &&
|
... | ... | |
288 |
286 |
}
|
289 |
287 |
}
|
290 |
288 |
|
|
289 |
//void lineFollowing_new(xyz) {}
|
|
290 |
|
|
291 |
void defuzz(colorMember (&member)[4], int (&rpmFuzzyCtrl)[2]){
|
|
292 |
// all sensors are equal
|
|
293 |
// if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == member[constants::DiWheelDrive::PROX_FRONT_LEFT] &&
|
|
294 |
// member[constants::DiWheelDrive::PROX_FRONT_LEFT] == member[constants::DiWheelDrive::PROX_FRONT_RIGHT] &&
|
|
295 |
// member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == member[constants::DiWheelDrive::PROX_WHEEL_RIGHT]) {
|
|
296 |
// // something is wrong -> stop
|
|
297 |
// copyRpmSpeed(rpmHalt, rpmFuzzyCtrl);
|
|
298 |
// // both front sensor detect a line
|
|
299 |
if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == BLACK &&
|
|
300 |
(member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == GREY)) {
|
|
301 |
// straight
|
|
302 |
copyRpmSpeed(global.rpmForward, rpmFuzzyCtrl);
|
|
303 |
// Deviation to right
|
|
304 |
} else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == BLACK
|
|
305 |
&& member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == WHITE){
|
|
306 |
copyRpmSpeed(global.rpmSoftLeft, rpmFuzzyCtrl);
|
|
307 |
// Deviation to left
|
|
308 |
}else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == BLACK
|
|
309 |
&& member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == BLACK){
|
|
310 |
copyRpmSpeed(global.rpmSoftRight, rpmFuzzyCtrl);
|
|
311 |
// Hard deviatio to right
|
|
312 |
}else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == GREY
|
|
313 |
&& member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == WHITE){
|
|
314 |
copyRpmSpeed(global.rpmHardLeft, rpmFuzzyCtrl);
|
|
315 |
// Hard deviation to left
|
|
316 |
}else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == GREY
|
|
317 |
&& member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == BLACK){
|
|
318 |
copyRpmSpeed(global.rpmHardRight, rpmFuzzyCtrl);
|
|
319 |
// Turn if white
|
|
320 |
}else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == WHITE
|
|
321 |
&& member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == WHITE ){
|
|
322 |
copyRpmSpeed(rpmTurnRight, rpmFuzzyCtrl);
|
|
323 |
}
|
|
324 |
}
|
|
325 |
|
291 |
326 |
// Line following by a fuzzy controler
|
292 |
327 |
void lineFollowing(int (&proximity)[4], int (&rpmFuzzyCtrl)[2]) {
|
293 |
328 |
// FUZZYFICATION
|
... | ... | |
312 |
347 |
global.robot.setLightColor(constants::LightRing::LED_NNE, memberToLed(member[constants::DiWheelDrive::PROX_FRONT_RIGHT]));
|
313 |
348 |
global.robot.setLightColor(constants::LightRing::LED_ENE, memberToLed(member[constants::DiWheelDrive::PROX_WHEEL_RIGHT]));
|
314 |
349 |
|
315 |
|
// chprintf((BaseSequentialStream*) &SD1, "Left: BLACK: %f, GREY: %f, WHITE: %f\r\n", leftFuzzyMemberValues[BLACK], leftFuzzyMemberValues[GREY], leftFuzzyMemberValues[WHITE]);
|
316 |
|
// chprintf((BaseSequentialStream*) &SD1, "Right: BLACK: %f, GREY: %f, WHITE: %f\r\n", rightFuzzyMemberValues[BLACK], rightFuzzyMemberValues[GREY], rightFuzzyMemberValues[WHITE]);
|
|
350 |
// chprintf((BaseSequentialStream*) &SD1, "Left: BLACK: %f, GREY: %f, WHITE: %f\r\n", leftWheelFuzzyMemberValues[BLACK], leftWheelFuzzyMemberValues[GREY], leftWheelFuzzyMemberValues[WHITE]);
|
|
351 |
// chprintf((BaseSequentialStream*) &SD1, "Right: BLACK: %f, GREY: %f, WHITE: %f\r\n", rightFuzzyMemberValues[BLACK], rightFuzzyMemberValues[GREY], rightFuzzyMemberValues[WHITE]);
|
317 |
352 |
|
318 |
353 |
// DEFUZZYFICATION
|
319 |
|
defuzzyfication(member, rpmFuzzyCtrl);
|
|
354 |
// defuzzyfication(member, rpmFuzzyCtrl);
|
|
355 |
defuzz(member, rpmFuzzyCtrl);
|
320 |
356 |
}
|
321 |
357 |
|
|
358 |
|
|
359 |
|
|
360 |
|
322 |
361 |
// Set the speed by the array
|
323 |
362 |
void setRpmSpeed(const int (&rpmSpeed)[2]) {
|
324 |
363 |
global.motorcontrol.setTargetRPM(rpmSpeed[constants::DiWheelDrive::LEFT_WHEEL] * 1000000, rpmSpeed[constants::DiWheelDrive::RIGHT_WHEEL] * 1000000);
|
... | ... | |
355 |
394 |
global.robot.setLightColor(led, Color(Color::BLACK));
|
356 |
395 |
}
|
357 |
396 |
running = false;
|
358 |
|
|
|
397 |
LineFollow lf;
|
359 |
398 |
/*
|
360 |
399 |
* LOOP
|
361 |
400 |
*/
|
... | ... | |
369 |
408 |
/*
|
370 |
409 |
* evaluate the accelerometer
|
371 |
410 |
*/
|
372 |
|
if (accel_z < -900 /*-0.9g*/) {
|
|
411 |
|
|
412 |
//Features over can: (Line Following)
|
|
413 |
//SetKP
|
|
414 |
//SetKI
|
|
415 |
//SetKd ?
|
|
416 |
//SetSleepTime
|
|
417 |
//SeForwardSpeed? or SetMaxSpeed
|
|
418 |
//DriveOnLeftLine
|
|
419 |
//DriveOnRightLine
|
|
420 |
|
|
421 |
//if accel_z<-900
|
|
422 |
//send can event (one time)
|
|
423 |
// Line following is started if amiro roteted
|
|
424 |
if (accel_z < -900 /*-0.9g*/) { //new: (can.allowLineFollowOnTurn && accel_z < 900) || can.startLineFollow optional feature
|
373 |
425 |
if (running) {
|
374 |
426 |
// stop the robot
|
375 |
427 |
running = false;
|
... | ... | |
400 |
452 |
vcnl4020AmbientLight[i] = global.vcnl4020[i].getAmbientLight();
|
401 |
453 |
vcnl4020Proximity[i] = global.vcnl4020[i].getProximityScaledWoOffset();
|
402 |
454 |
}
|
403 |
|
|
404 |
|
// chprintf((BaseSequentialStream*) &SD1, "0x%04X 0x%04X 0x%04X 0x%04X\n",
|
405 |
|
// vcnl4020Proximity[constants::DiWheelDrive::PROX_WHEEL_LEFT],
|
406 |
|
// vcnl4020Proximity[constants::DiWheelDrive::PROX_FRONT_LEFT],
|
407 |
|
// vcnl4020Proximity[constants::DiWheelDrive::PROX_FRONT_RIGHT],
|
408 |
|
// vcnl4020Proximity[constants::DiWheelDrive::PROX_WHEEL_RIGHT]);
|
409 |
|
|
|
455 |
lf.followLine(vcnl4020Proximity, &global);
|
|
456 |
// chprintf((BaseSequentialStream*) &SD1, "0x%04X 0x%04X 0x%04X 0x%04X\n",
|
|
457 |
// vcnl4020Proximity[constants::DiWheelDrive::PROX_WHEEL_LEFT],
|
|
458 |
// vcnl4020Proximity[constants::DiWheelDrive::PROX_FRONT_LEFT],
|
|
459 |
// vcnl4020Proximity[constants::DiWheelDrive::PROX_FRONT_RIGHT],
|
|
460 |
// vcnl4020Proximity[constants::DiWheelDrive::PROX_WHEEL_RIGHT]);
|
|
461 |
//if (configLineFollowing==2)
|
|
462 |
// lineFollownew
|
|
463 |
//else
|
410 |
464 |
lineFollowing(vcnl4020Proximity, rpmFuzzyCtrl);
|
411 |
465 |
setRpmSpeed(rpmFuzzyCtrl);
|
412 |
466 |
}
|