forked from log0/video_streaming_with_flask_example
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrobot.ino
380 lines (304 loc) · 9.45 KB
/
robot.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
/*
Project : Robot control program
Author : Bin Xiao, Xu Guo, Peter Guan
Date : 11/12/2015
Version : 1
Version 0 is developed by Bin Xiao, Xu and Peter made some modification for new project usage.
CopyRight:
Reserved by the author.
Please keep this claim for academic usage.
For commercial use, please contact the author.
*/
#include <SoftwareSerial.h>
#include <Wire.h>
#include <Servo.h>
#include "mytypes.h" // for the data structures defined by users and prototype declaration for functions used these data structures
//SoftwareSerial mySerial(10, 11); // RX, TX
//ultra sonic sensor pin for Front
//#define trigPinF 2
//#define echoPinF 3
#define STILL_NUM 1500
#define DELTA_SPEED 30
#define MAX_SPEED 200
#define BACK_SPEED 200
#define ROT_SPEED 60 //Xu changed this from 200 to 60
//#define DIST_STOP 15 // robot will stop when distance to front < DIST_STOP
#define DIST_FAR_STOP 30
#define RIGHT_CALIBERATE 3
#define LEFT_CALIBERATE 1
#define DEFAULT_ACTION 15
#define CMD_START 13
#define SLAVE_ADDRESS 0x04
const double TimeHalfRound = 2.3;
const double rotateFactor = 0.40;
const double RIGHT_ANGLE = PI / 2.0; // 90 degree
const double TINY_ANGLE = 20 * PI / 180;
long duration; //for distance sensor
//------for distance detecting-------
//------not using this----------
//int gPins[3][2]={ { trigPinF,echoPinF } , {trigPinL,echoPinL },{ trigPinR,echoPinR } };
//int gPins[1][2] = { { trigPinF, echoPinF } };
float t = 0;
uint8_t cmd = DEFAULT_ACTION;
uint8_t serverCmd = DEFAULT_ACTION; //DEFAULT_ACTION for do nothing
//1 startUp
//2 stop
//3 for turn left
//4 for turn right
//5 speedup
//6 speeddown
//7 for move backward
//8 tinyLeft
//9 tinyRight
uint8_t request = DEFAULT_ACTION;
uint8_t action = DEFAULT_ACTION;
int backCount = 0; //for auto backWard, not using
uint8_t i = 0;
//uint8_t readFlag = 0;
Servo servoLeft;
Servo servoRight;
//--------------------------------callback function for I2C---------------------------------
// callback for received data
void receiveData(int byteCount) {
while (Wire.available()) {
serverCmd = Wire.read(); //read from PI to get action value
Serial.print("serverCmd received: ");
Serial.println(serverCmd);
if (serverCmd > 9)
request = serverCmd;
else
action = serverCmd;
}
//readFlag = 1;
}
// callback for sending data
void sendData() { //send x, y, direc, pwm back to pi, after receiving the action
if (request != DEFAULT_ACTION) {
Wire.write(0);
//Wire.write(rx64data[0]);
//Serial.println("writing to pi");
//Serial.println(rx64data[request]);
request = DEFAULT_ACTION;
}
else {
Wire.write(0xff);
}
}
//------------------------------------------------------------------------------------------
//------------------------- functins related to robot control --------------------------------
RobotInfo gCurInfo;
long readDistSensor(int trigpin, int echopin) {
long distance = 0;
digitalWrite(trigpin, LOW); // Added this line
delayMicroseconds(2); // Added this line
digitalWrite(trigpin, HIGH);
delayMicroseconds(10); // Added this line
digitalWrite(trigpin, LOW);
duration = pulseIn(echopin, HIGH);
distance = (duration / 2) / 29.1;
return (distance);
}
/* long getDistance( Dire mdir ) {
long dt = readDistSensor( gPins[mdir][0], gPins[mdir][1] );
//Serial.println("I am here 1.1.1");
while (( dt <= 1 ) || (dt >= 1000) ) {
dt = readDistSensor( gPins[mdir][0], gPins[mdir][1] );
// Serial.print("Direction=");
// Serial.println(mdir);
// Serial.print(",value=");
// Serial.println(dt);
// delay(10);
}
//Serial.println("I am here 1.2");
return dt;
} */
void setRobotSpeed( int curSpeed ) {
servoLeft.writeMicroseconds(STILL_NUM + curSpeed + LEFT_CALIBERATE);
servoRight.writeMicroseconds(STILL_NUM - curSpeed - RIGHT_CALIBERATE);
//delay(250); //xiao bin commented it out, since we check sensor to stop
}
void stayput() { // stop the robot
servoLeft.writeMicroseconds(STILL_NUM);
servoRight.writeMicroseconds(STILL_NUM);
delay(100);
}
inline double getTime2Delay( double angle) {
return ( rotateFactor * TimeHalfRound * angle / PI * 1000); /* return in millisecond */
}
void turnLeft(double angle) {
double delayTime = getTime2Delay(angle);
stayput();
servoLeft.writeMicroseconds(STILL_NUM - ROT_SPEED);
servoRight.writeMicroseconds(STILL_NUM - ROT_SPEED);
delay(delayTime);
stayput();
}
void turnRight(double angle) {
double delayTime = getTime2Delay(angle);
stayput();
servoLeft.writeMicroseconds(STILL_NUM + ROT_SPEED);
servoRight.writeMicroseconds(STILL_NUM + ROT_SPEED);
delay(delayTime * 1.2);
stayput();
}
// assume g_angle =0 before this call
void turnAngle( double angle ) {
// drive servor
if ( angle < 0.0 )
turnLeft(-angle);
else if (angle > 0.0 ) {
turnRight(angle);
}
stayput();
}
//----------------------------setup function-------------------------
void setup() {
Serial.begin(9600);
Serial.println("SETUP");
Wire.begin(SLAVE_ADDRESS);
// define callbacks for i2c communication
Wire.onReceive(receiveData);
//Wire.onRequest(sendData); //for sending data from slave to master, not using
//
servoLeft.attach(13);
servoRight.attach(12);
servoLeft.writeMicroseconds(STILL_NUM);
servoRight.writeMicroseconds(STILL_NUM);
// pinMode(trigPinF, OUTPUT);
// pinMode(echoPinF, INPUT);
//
//
//gCurInfo.direc = 0;
gCurInfo.curSpeed = 0;
gCurInfo.oldSpeed = 0;
//gCurInfo.stop4close = 0;
delay(5000);
Serial.println("SETUPend");
}
void updateCurInfo() {
Serial.println("updateCurInfo");
Serial.println("Done-updateCurInfo");
}
void nothing() {
// do nothing.
Serial.println("Do nothing");
}
void startUp() {
Serial.print("Start up");
if ( gCurInfo.curSpeed == 0 ) { // from still to move, if move then do not change speed
gCurInfo.curSpeed = DELTA_SPEED;
setRobotSpeed( gCurInfo.curSpeed );
}
}
void getTemp() {
Serial.print("get getTemp");
sendData(65);
}
void stayStop() {
Serial.print("Stop");
gCurInfo.curSpeed = 0;
gCurInfo.oldSpeed = 0;
setRobotSpeed( gCurInfo.curSpeed );
}
void goLeft() {
Serial.print("Turn to left");
turnLeft(RIGHT_ANGLE);
/*
if( gCurInfo.stop4close ) {
gCurInfo.curSpeed = gCurInfo.oldSpeed; // restore the speed before stop if stop because too close to wall
} */
gCurInfo.curSpeed = 0;
//gCurInfo.stop4close = 0;
setRobotSpeed( gCurInfo.curSpeed );
}
void goRight() {
Serial.print("Turn to right");
turnRight(RIGHT_ANGLE);
/* if( gCurInfo.stop4close ) {
gCurInfo.curSpeed = gCurInfo.oldSpeed; // restore the speed before stop if stop because too close to wall
} */
gCurInfo.curSpeed = 0;
//gCurInfo.stop4close = 0;
setRobotSpeed( gCurInfo.curSpeed );
}
void stepOn() {
Serial.print("Accelerate !");
if ( gCurInfo.stop4close )
return;
gCurInfo.curSpeed += DELTA_SPEED;
if ( gCurInfo.curSpeed > MAX_SPEED) {
gCurInfo.curSpeed = MAX_SPEED;
}
setRobotSpeed( gCurInfo.curSpeed );
}
void slowDown() {
Serial.print("Slow Down");
if ( gCurInfo.curSpeed >= DELTA_SPEED ) { //if you want backward , can replace >=DELTA_SPEED with > -MAX_SPEED
gCurInfo.curSpeed -= DELTA_SPEED;
} else {
return ;
}
setRobotSpeed( gCurInfo.curSpeed );
}
void backWard() {
stayput();
Serial.print("backWard to 20+ cm");
gCurInfo.curSpeed = - DELTA_SPEED;
backCount = 0;
setRobotSpeed( gCurInfo.curSpeed );
}
void tinyLeft() {
double delayTime = getTime2Delay(TINY_ANGLE);
stayput();
servoRight.writeMicroseconds(STILL_NUM - ROT_SPEED);
//delay(delayTime);
//stayput();
//setRobotSpeed( gCurInfo.curSpeed );
}
void tinyRight() {
double delayTime = getTime2Delay(TINY_ANGLE);
stayput();
servoLeft.writeMicroseconds(STILL_NUM + ROT_SPEED);
//delay(delayTime);
//stayput();
//setRobotSpeed( gCurInfo.curSpeed );
}
typedef void (*funcPt)();
funcPt robotActions[] = {&startUp, &stayStop, &goLeft, &goRight, &stepOn, &slowDown , &backWard , &tinyLeft, &tinyRight, ¬hing, &getTemp};
const int actionNum = sizeof(robotActions) / sizeof(robotActions[0]);
void robotDoSomething(uint8_t cmd ) {
Serial.print("get a command:");
Serial.println(cmd);
if (cmd > CMD_START) {
Serial.print("Not a command:");
return;
}
//cmd-=CMD_START;
if (cmd >= actionNum ) {
Serial.print("Wrong command:");
Serial.println(cmd);
return ;
}
robotActions[cmd]();
}
//--------------------------------main loop--------------------------------//
void loop()
{
//-----code for receiving cmd from USB port,so we can test the robot through pc's serial monitor-----
Serial.println("loop start..");
if (Serial.available()) {
char s;
s = Serial.read();
action = (uint8_t)(s - 48);
}
//-----end------
//updateCurInfo();
//-----for debug-----
Serial.println("LOOP3..");
Serial.print("action: ");
Serial.println(action);
//-----end-----
robotDoSomething(action);
action = DEFAULT_ACTION;
delay(200);
}