Revision 1b3adcdd devices/DiWheelDrive/userthread.cpp

View differences:

devices/DiWheelDrive/userthread.cpp
42 42
// BLACK is the line itselfe
43 43
// GREY is the boarder between the line and the surface
44 44
// WHITE is the common surface
45
enum colorMember : uint8_t {
46
	BLACK=0,
47
	GREY=1,
48
	WHITE=2
49
};
45
// enum colorMember : uint8_t {
46
// 	BLACK=0,
47
// 	GREY=1,
48
// 	WHITE=2
49
// };
50 50

  
51 51
// a buffer for the z-value of the accelerometer
52 52
int16_t accel_z;
......
57 57
int policyCounter = 0; // Do not change this, it points to the beginning of the policy
58 58

  
59 59
// Different speed settings (all values in "rounds per minute")
60
const int rpmTurnLeft[2] = {-10, 10};
61
const int rpmTurnRight[2] = {rpmTurnLeft[1],rpmTurnLeft[0]};
62
const int rpmHalt[2] = {0, 0};
60
// const int rpmTurnLeft[2] = {-10, 10};
61
// const int rpmTurnRight[2] = {rpmTurnLeft[1],rpmTurnLeft[0]};
62
// const int rpmHalt[2] = {0, 0};
63 63

  
64 64
// Definition of the fuzzyfication function
65 65
//  | Membership
......
71 71
// All values are "raw sensor values"
72 72
/* Use these values for white ground surface (e.g. paper) */
73 73

  
74
const int blackStartFalling = 0x1000; // Where the black curve starts falling
75
const int blackOff = 0x1800; // Where no more black is detected
76
const int whiteStartRising = 0x2800; // Where the white curve starts rising
77
const int whiteOn = 0x6000; // Where the white curve has reached the maximum value
78
const int greyMax = (whiteOn + blackStartFalling) / 2; // Where grey has its maximum
79
const int greyStartRising = blackStartFalling; // Where grey starts rising
80
const int greyOff = whiteOn; // Where grey is completely off again
74
// const int blackStartFalling = 0x1000; // Where the black curve starts falling
75
// const int blackOff = 0x1800; // Where no more black is detected
76
// const int whiteStartRising = 0x2800; // Where the white curve starts rising
77
// const int whiteOn = 0x6000; // Where the white curve has reached the maximum value
78
// const int greyMax = (whiteOn + blackStartFalling) / 2; // Where grey has its maximum
79
// const int greyStartRising = blackStartFalling; // Where grey starts rising
80
// const int greyOff = whiteOn; // Where grey is completely off again
81 81

  
82 82
/* Use these values for gray ground surfaces */
83 83
/*
......
111 111
	// chprintf((BaseSequentialStream*) &SD1, "Speed left: %d, Speed right: %d\r\n", target[0], target[1]);
112 112
}
113 113

  
114
// Fuzzyfication of the sensor values
115
void fuzzyfication(int sensorValue, float (&fuzziedValue)[3]) {
116
	if (sensorValue < blackStartFalling ) {
117
		// Only black value
118
		fuzziedValue[BLACK] = 1.0f;
119
		fuzziedValue[GREY] = 0.0f;
120
		fuzziedValue[WHITE] = 0.0f;
121
	} else if (sensorValue > whiteOn ) {
122
		// Only white value
123
		fuzziedValue[BLACK] = 0.0f;
124
		fuzziedValue[GREY] = 0.0f;
125
		fuzziedValue[WHITE] = 1.0f;
126
	} else if ( sensorValue < greyMax) {
127
		// Some greyisch value between black and grey
128

  
129
		// Black is going down
130
		if ( sensorValue > blackOff) {
131
			fuzziedValue[BLACK] = 0.0f;
132
		} else {
133
			fuzziedValue[BLACK] = static_cast<float>(sensorValue-blackOff) / (blackStartFalling-blackOff);
134
		}
135

  
136
		// Grey is going up
137
		if ( sensorValue < greyStartRising) {
138
			fuzziedValue[GREY] = 0.0f;
139
		} else {
140
			fuzziedValue[GREY] = static_cast<float>(sensorValue-greyStartRising) / (greyMax-greyStartRising);
141
		}
142

  
143
		// White is absent
144
		fuzziedValue[WHITE] = 0.0f;
145

  
146
	} else if ( sensorValue >= greyMax) {
147
		// Some greyisch value between grey white
148

  
149
		// Black is absent
150
		fuzziedValue[BLACK] = 0.0f;
151

  
152
		// Grey is going down
153
		if ( sensorValue < greyOff) {
154
			fuzziedValue[GREY] = static_cast<float>(sensorValue-greyOff) / (greyMax-greyOff);
155
		} else {
156
			fuzziedValue[GREY] = 0.0f;
157
		}
158

  
159
		// White is going up
160
		if ( sensorValue < whiteStartRising) {
161
			fuzziedValue[WHITE] = 0.0f;
162
		} else {
163
			fuzziedValue[WHITE] = static_cast<float>(sensorValue-whiteStartRising) / (whiteOn-whiteStartRising);
164
		}
165
	}
166
}
167

  
168
// Return the color, which has the highest fuzzy value
169
colorMember getMember(float (&fuzzyValue)[3]) {
170
	colorMember member;
171

  
172
	if (fuzzyValue[BLACK] > fuzzyValue[GREY])
173
		if (fuzzyValue[BLACK] > fuzzyValue[WHITE])
174
			member = BLACK;
175
		else
176
			member = WHITE;
177
	else
178
		if (fuzzyValue[GREY] > fuzzyValue[WHITE])
179
			member = GREY;
180
		else
181
			member = WHITE;
182

  
183
	return member;
184
}
185

  
186
// Get a crisp output for the steering commands
187
void defuzzyfication(colorMember (&member)[4], int (&rpmFuzzyCtrl)[2]) {
188

  
189
	// all sensors are equal
190
	if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == member[constants::DiWheelDrive::PROX_FRONT_LEFT] &&
191
	    member[constants::DiWheelDrive::PROX_FRONT_LEFT] == member[constants::DiWheelDrive::PROX_FRONT_RIGHT] &&
192
	    member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == member[constants::DiWheelDrive::PROX_WHEEL_RIGHT]) {
193
		// something is wrong -> stop
194
		copyRpmSpeed(rpmHalt, rpmFuzzyCtrl);
195
	// both front sensor detect a line
196
	} else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == BLACK &&
197
	    member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == BLACK) {
198
		// straight
199
		copyRpmSpeed(global.rpmForward, rpmFuzzyCtrl);
200
	// exact one front sensor detects a line
201
	} else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == BLACK ||
202
	           member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == BLACK) {
203
		// soft correction
204
		if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == GREY) {
205
			// soft right
206
			copyRpmSpeed(global.rpmSoftRight, rpmFuzzyCtrl);
207
		} else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == WHITE) {
208
			// hard right
209
			copyRpmSpeed(global.rpmHardRight, rpmFuzzyCtrl);
210
		} else if (member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == GREY) {
211
			// soft left
212
			copyRpmSpeed(global.rpmSoftLeft, rpmFuzzyCtrl);
213
		} else if (member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == WHITE) {
214
			// hard left
215
			copyRpmSpeed(global.rpmHardLeft, rpmFuzzyCtrl);
216
		}
217
	// both wheel sensors detect a line
218
	} else if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == BLACK &&
219
	           member[constants::DiWheelDrive::PROX_WHEEL_RIGHT] == BLACK) {
220
		// something is wrong -> stop
221
		copyRpmSpeed(rpmHalt, rpmFuzzyCtrl);
222
	// exactly one wheel sensor detects a line
223
	} else if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == BLACK ||
224
	           member[constants::DiWheelDrive::PROX_WHEEL_RIGHT] == BLACK) {
225
		if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == BLACK) {
226
			// turn left
227
			copyRpmSpeed(rpmTurnLeft, rpmFuzzyCtrl);
228
		} else if (member[constants::DiWheelDrive::PROX_WHEEL_RIGHT] == BLACK) {
229
			// turn right
230
			copyRpmSpeed(rpmTurnRight, rpmFuzzyCtrl);
231
		}
232
	// both front sensors may detect a line
233
	} else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == GREY &&
234
	           member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == GREY) {
235
		if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == GREY) {
236
			// turn left
237
			copyRpmSpeed(rpmTurnLeft, rpmFuzzyCtrl);
238
		} else if (member[constants::DiWheelDrive::PROX_WHEEL_RIGHT] == GREY) {
239
			// turn right
240
			copyRpmSpeed(rpmTurnRight, rpmFuzzyCtrl);
241
		}
242
	// exactly one front sensor may detect a line
243
	} else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == GREY ||
244
	           member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == GREY) {
245
		if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == GREY) {
246
			// turn left
247
			copyRpmSpeed(rpmTurnLeft, rpmFuzzyCtrl);
248
		} else if (member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == GREY) {
249
			// turn right
250
			copyRpmSpeed(rpmTurnRight, rpmFuzzyCtrl);
251
		}
252
	// both wheel sensors may detect a line
253
	} else if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == GREY &&
254
	           member[constants::DiWheelDrive::PROX_WHEEL_RIGHT] == GREY) {
255
		// something is wrong -> stop
256
		copyRpmSpeed(rpmHalt, rpmFuzzyCtrl);
257
	// exactly one wheel sensor may detect a line
258
	} else if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == GREY ||
259
	           member[constants::DiWheelDrive::PROX_WHEEL_RIGHT] == GREY) {
260
		if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == GREY) {
261
			// turn left
262
			copyRpmSpeed(rpmTurnLeft, rpmFuzzyCtrl);
263
		} else if (member[constants::DiWheelDrive::PROX_WHEEL_RIGHT] == GREY) {
264
			// turn right
265
			copyRpmSpeed(rpmTurnRight, rpmFuzzyCtrl);
266
		}
267
	// no sensor detects anything 
268
	} else {
269
		// line is lost -> stop
270
		copyRpmSpeed(rpmHalt, rpmFuzzyCtrl);
271
	}
272

  
273
	return;
274
}
275

  
276
Color memberToLed(colorMember member) {
277
	switch (member) {
278
		case BLACK:
279
			return Color(Color::GREEN);
280
		case GREY:
281
			return Color(Color::YELLOW);
282
		case WHITE:
283
			return Color(Color::RED);
284
		default:
285
			return Color(Color::WHITE);
286
	}
287
}
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(rpmTurnLeft, 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(rpmTurnRight, rpmFuzzyCtrl);
319
	// stop if white
320
	}else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == WHITE
321
		&& member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == WHITE ){
322
			copyRpmSpeed(rpmHalt, rpmFuzzyCtrl);
323
	}
324
}
325

  
326
// Line following by a fuzzy controler
327
void lineFollowing(int (&proximity)[4], int (&rpmFuzzyCtrl)[2]) {
328
	// FUZZYFICATION
329
	// First we need to get the fuzzy value for our 3 values {BLACK, GREY, WHITE}
330
	float leftWheelFuzzyMemberValues[3], leftFrontFuzzyMemberValues[3], rightFrontFuzzyMemberValues[3], rightWheelFuzzyMemberValues[3];
331
	fuzzyfication(proximity[constants::DiWheelDrive::PROX_WHEEL_LEFT], leftWheelFuzzyMemberValues);
332
	fuzzyfication(proximity[constants::DiWheelDrive::PROX_FRONT_LEFT], leftFrontFuzzyMemberValues);
333
	fuzzyfication(proximity[constants::DiWheelDrive::PROX_FRONT_RIGHT], rightFrontFuzzyMemberValues);
334
	fuzzyfication(proximity[constants::DiWheelDrive::PROX_WHEEL_RIGHT], rightWheelFuzzyMemberValues);
335

  
336
	// INFERENCE RULE DEFINITION
337
	// Get the member for each sensor
338
	colorMember member[4];
339
	member[constants::DiWheelDrive::PROX_WHEEL_LEFT] = getMember(leftWheelFuzzyMemberValues);
340
	member[constants::DiWheelDrive::PROX_FRONT_LEFT] = getMember(leftFrontFuzzyMemberValues);
341
	member[constants::DiWheelDrive::PROX_FRONT_RIGHT] = getMember(rightFrontFuzzyMemberValues);
342
	member[constants::DiWheelDrive::PROX_WHEEL_RIGHT] = getMember(rightWheelFuzzyMemberValues);
343

  
344
	// visualize sensors via LEDs
345
	global.robot.setLightColor(constants::LightRing::LED_WNW, memberToLed(member[constants::DiWheelDrive::PROX_WHEEL_LEFT]));
346
	global.robot.setLightColor(constants::LightRing::LED_NNW, memberToLed(member[constants::DiWheelDrive::PROX_FRONT_LEFT]));
347
	global.robot.setLightColor(constants::LightRing::LED_NNE, memberToLed(member[constants::DiWheelDrive::PROX_FRONT_RIGHT]));
348
	global.robot.setLightColor(constants::LightRing::LED_ENE, memberToLed(member[constants::DiWheelDrive::PROX_WHEEL_RIGHT]));
349

  
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]);
352

  
353
	// DEFUZZYFICATION
354
	// defuzzyfication(member, rpmFuzzyCtrl);
355
	defuzz(member, rpmFuzzyCtrl);
356
}
357

  
358

  
359

  
360 114

  
361 115
// Set the speed by the array
362 116
void setRpmSpeed(const int (&rpmSpeed)[2]) {
......
452 206
                vcnl4020AmbientLight[i] = global.vcnl4020[i].getAmbientLight();
453 207
                vcnl4020Proximity[i] = global.vcnl4020[i].getProximityScaledWoOffset();
454 208
            }
455
			lf.stableFollow(vcnl4020Proximity, rpmFuzzyCtrl, &global);
209
			// lf.stableFollow(vcnl4020Proximity, rpmFuzzyCtrl, &global);
456 210
            // chprintf((BaseSequentialStream*) &SD1, "0x%04X 0x%04X 0x%04X 0x%04X\n",
457 211
            //         vcnl4020Proximity[constants::DiWheelDrive::PROX_WHEEL_LEFT],
458 212
            //         vcnl4020Proximity[constants::DiWheelDrive::PROX_FRONT_LEFT],

Also available in: Unified diff