Statistics
| Branch: | Tag: | Revision:

amiro-os / devices / DiWheelDrive / userthread.cpp @ 9090cc7e

History | View | Annotate | Download (35.063 KB)

1
#include "userthread.hpp"
2
#include "amiro_map.hpp"
3
#include "global.hpp"
4
#include "linefollow.hpp"
5

    
6
using namespace amiro;
7

    
8
extern Global global;
9

    
10
// a buffer for the z-value of the accelerometer
11
int16_t accel_z;
12
bool running = false;
13

    
14

    
15
/**
16
 * Set speed.
17
 *
18
 * @param rpmSpeed speed for left and right wheel in rounds/min
19
 */
20
void UserThread::setRpmSpeedFuzzy(const int (&rpmSpeed)[2]) {
21
  global.motorcontrol.setTargetRPM(rpmSpeed[constants::DiWheelDrive::LEFT_WHEEL] * 1000000, rpmSpeed[constants::DiWheelDrive::RIGHT_WHEEL] * 1000000);
22
}
23

    
24
void UserThread::setRpmSpeed(const int (&rpmSpeed)[2]) {
25
  global.motorcontrol.setTargetRPM(rpmSpeed[constants::DiWheelDrive::LEFT_WHEEL], rpmSpeed[constants::DiWheelDrive::RIGHT_WHEEL]);
26
}
27

    
28
void UserThread::lightOneLed(Color color, int idx){
29
  global.robot.setLightColor(idx, Color(color));
30
}
31

    
32
void UserThread::lightAllLeds(Color color){
33
  int led = 0;
34
  for(led=0; led<8; led++){
35
        lightOneLed(color, led);
36
      }
37
}
38

    
39
void UserThread::showChargingState(){
40
  uint8_t numLeds = global.robot.getPowerStatus().state_of_charge / 12;
41
  Color color = Color::GREEN;
42
  if (numLeds <= 2){
43
    color = Color::RED;
44
  }else if(numLeds <= 6){
45
    color = Color::YELLOW;
46
  }
47
  for (int i=0; i<numLeds; i++){
48
    lightOneLed(color, i);
49
    this->sleep(300);
50
  }
51
  this->sleep(1000);
52
  lightAllLeds(Color::BLACK);
53
}
54

    
55
void UserThread::chargeAsLED(){
56
  uint8_t numLeds = global.robot.getPowerStatus().state_of_charge / 12;
57
  Color color = Color::GREEN;
58
  if (numLeds <= 2){
59
    color = Color::RED;
60
  }else if(numLeds <= 6){
61
    color = Color::YELLOW;
62
  }
63
  for (int i=0; i<numLeds; i++){
64
    lightOneLed(color, i);
65
    // this->sleep(300);
66
  }
67
  // this->sleep(1000);
68
  // lightAllLeds(Color::BLACK);
69
}
70

    
71
// ----------------------------------------------------------------
72

    
73
void UserThread::getProxySectorVals(uint16_t (&proxVals)[8], uint16_t (&sProx)[8]){
74
  for (int i=0; i<8; i++){
75
    sProx[i] = (proxVals[i] < proxVals[(i+1) % 8]) ? proxVals[i] : proxVals[(i+1) % 8];
76
    // chprintf((BaseSequentialStream*)&global.sercanmux1, "%d: %d, ", i, sProx[i]);
77

    
78
  }
79
    // chprintf((BaseSequentialStream*)&global.sercanmux1, "\n");
80

    
81
}
82

    
83

    
84
void UserThread::getMaxFrontSectorVal(uint16_t (&sProx)[8], int32_t &sPMax){
85
  for (int i=2; i<5; i++){
86
    sPMax = (sPMax < sProx[i]) ? sProx[i] : sPMax;
87
  }
88
}
89

    
90
void UserThread::proxSectorSpeedCorrection(int (&rpmSpeed)[2], uint16_t (&proxVals)[8]){
91
  int i;
92
  uint16_t sProx[8];
93
  int32_t sPMax = 0;
94
  getProxySectorVals(proxVals, sProx);
95
  getMaxFrontSectorVal(sProx, sPMax);
96

    
97
  int32_t speedL = rpmSpeed[0] - (sPMax * pCtrl.pFactor);
98
  int32_t speedR = rpmSpeed[1] - (sPMax * pCtrl.pFactor);
99

    
100

    
101

    
102
  if(sPMax > pCtrl.threshMid){
103
      rpmSpeed[0] = 0;
104
      rpmSpeed[1] = 0;
105
      pCtrl.staticCont++;
106
  }else if((speedL > 0) || (speedR > 0)){
107
    pCtrl.staticCont = 0;
108
    rpmSpeed[0] = speedL;
109
    rpmSpeed[1] = speedR;
110
  }else{
111
    rpmSpeed[0] = 4000000 + (rpmSpeed[0] - global.rpmForward[0] * 1000000);
112
    rpmSpeed[1] = 4000000 + (rpmSpeed[1] - global.rpmForward[0] * 1000000);
113
  }
114

    
115
  for(i=4; i<5; i++){
116
    if ((proxVals[i] > pCtrl.threshMid) && (proxVals[i+1] > pCtrl.threshLow)){
117
      rpmSpeed[0] = -5000000 ;
118
      rpmSpeed[1] = -5000000 ;
119
      // pCtrl.staticCont++;
120
      break;
121
    }
122
  }
123
  chargeAsLED();
124

    
125
  // chprintf((BaseSequentialStream*)&global.sercanmux1, "Max: %d factor: %d, Panel: %d SpeedL: %d SpeedR: %d ActualL: %d ActualR: %d\n",sPMax,  pCtrl.pFactor,  sPMax * pCtrl.pFactor, speedL, speedR, rpmSpeed[0], rpmSpeed[1]);
126

    
127

    
128
}
129
// -------------------------------------------------------------------
130

    
131

    
132
void UserThread::preventCollision( int (&rpmSpeed)[2], uint16_t (&proxVals)[8]) {
133

    
134
  if((proxVals[3] > pCtrl.threshLow) || (proxVals[4] > pCtrl.threshLow)){
135
      rpmSpeed[0] = rpmSpeed[0] / 2;
136
      rpmSpeed[1] = rpmSpeed[1] / 2;
137
  }
138

    
139
  if((proxVals[3] > pCtrl.threshMid) || (proxVals[4] > pCtrl.threshMid)){
140
      rpmSpeed[0] = rpmSpeed[0] / 3;
141
      rpmSpeed[1] = rpmSpeed[1] / 3;
142
  }
143

    
144
  if((proxVals[3] > pCtrl.threshHigh) || (proxVals[4] > pCtrl.threshHigh)){
145
      rpmSpeed[0] = 0;
146
      rpmSpeed[1] = 0;
147
      utCount.ringProxCount++;
148
  }else{
149
    utCount.ringProxCount = 0;
150
  }
151

    
152
}
153

    
154

    
155
/**
156
 * Blocks as long as the position changes.
157
 */
158
void UserThread::checkForMotion(){
159
  bool motion = true;
160
  int led = 0;
161
  types::position oldPos = global.odometry.getPosition();
162
  while(motion){
163
    this->sleep(200);
164
    types::position tmp = global.odometry.getPosition();
165
    motion = oldPos.x != tmp.x; //abs(oldPos.x - tmp.x)+ abs(oldPos.y - tmp.y)+abs(oldPos.z - tmp.z);
166
    oldPos = tmp;
167
    global.robot.setLightColor((led + 1) % 8, Color(Color::YELLOW));
168
    global.robot.setLightColor(led % 8, Color(Color::BLACK));
169
    led++;
170
  }
171
  lightAllLeds(Color::BLACK);
172
}
173

    
174
bool UserThread::checkFrontalObject(){
175
  uint32_t thresh = pCtrl.threshMid;
176
  uint32_t prox;
177
  for(int i=0; i<8; i++){
178
    prox = global.robot.getProximityRingValue(i);
179
    if((i == 3) || (i == 4)){
180
      if(prox < thresh){
181
        return false;
182
      }
183
    }else{
184
      if(prox > thresh){
185
        return false;
186
      }
187
    }
188
  }
189
  return true;
190
}
191

    
192
bool UserThread::checkPinVoltage(){
193
  return global.ltc4412.isPluggedIn();
194
}
195

    
196
bool UserThread::checkPinEnabled(){
197
  return global.ltc4412.isEnabled();
198
}
199

    
200
int UserThread::checkDockingSuccess(){
201
  // setRpmSpeed(stop);
202
  checkForMotion();
203
  int success = 0;
204
  // global.odometry.resetPosition();
205
  types::position start = global.startPos = global.odometry.getPosition();
206
  global.motorcontrol.setMotorEnable(false);
207
  this->sleep(1000);
208
  types::position stop_ = global.endPos = global.odometry.getPosition();
209

    
210
  // Amiro moved, docking was not successful
211
  // if ((start.x + stop_.x)  || (start.y + stop_.y)){
212
  if (abs(start.x - stop_.x) > 200 /* || (start.y + stop_.y) */){
213
    lightAllLeds(Color::RED);
214
    // Enable Motor again if docking was not successful
215
    global.motorcontrol.setMotorEnable(true);
216
    success = 0;
217
  }else{
218
    lightAllLeds(Color::GREEN);
219
    success = 1;
220
  }
221

    
222
  // this->sleep(500);
223
  lightAllLeds(Color::BLACK);
224
  return success;
225
}
226

    
227
int UserThread::getProxyRingSum(){
228
  int prox_sum = 0;
229
  for(int i=0; i<8;i++){
230
    prox_sum += global.robot.getProximityRingValue(i);;
231
  }
232
  return prox_sum;
233
}
234

    
235
int32_t UserThread::meanDeviation(uint16_t a, uint16_t b){
236
  int32_t diff = a - b;
237
  int32_t res = 0;
238
  devCor.proxbuf[devCor.pCount] = (diff*100)/((a+b)/2);
239
  for (int i = 0; i< PROX_DEVIATION_MEAN_WINDOW; i++){
240
    res += devCor.proxbuf[i];
241
  }
242
  devCor.pCount++;
243
  devCor.pCount = devCor.pCount % PROX_DEVIATION_MEAN_WINDOW;
244

    
245
  devCor.currentDeviation =  res / PROX_DEVIATION_MEAN_WINDOW;
246
  return devCor.currentDeviation;
247
}
248

    
249
void setAttributes(uint8_t (&map)[MAX_NODES][NODE_ATTRIBUTES],
250
                          uint8_t id, uint8_t l, uint8_t r, uint8_t att) {
251
  map[id][0] = l;
252
  map[id][1] = r;
253
  map[id][2] = att;
254
}
255

    
256
UserThread::UserThread() :
257
  chibios_rt::BaseStaticThread<USER_THREAD_STACK_SIZE>()
258
{
259
}
260

    
261
UserThread::~UserThread()
262
{
263
}
264

    
265
msg_t
266
UserThread::main()
267
{
268
  /*
269
   * SETUP
270
   */
271
  // User thread state:
272

    
273
  for (uint8_t led = 0; led < 8; ++led) {
274
    global.robot.setLightColor(led, Color(Color::BLACK));
275
  }
276
  running = false;
277
  LineFollowStrategy lStrategy = LineFollowStrategy::EDGE_RIGHT;
278
  LineFollow lf(&global);
279
  AmiroMap map(&global);
280
  /*
281
   * LOOP
282
   */
283
  while (!this->shouldTerminate())
284
  {
285
    /*
286
    * read accelerometer z-value
287
    */
288
    accel_z = global.lis331dlh.getAccelerationForce(LIS331DLH::AXIS_Z);
289

    
290
    if (accel_z < -900 /*-0.9g*/) {
291
      // Start line following when AMiRo is rotated
292
      if(currentState == states::INACTIVE){
293
        newState = states::FOLLOW_LINE;
294
      }else{
295
        newState = states::IDLE;
296
      }
297
      lightAllLeds(Color::GREEN);
298
      this->sleep(1000);
299
      lightAllLeds(Color::BLACK);
300

    
301
    // If message was received handle it here:
302
    } else if(global.msgReceived){
303
      global.msgReceived = false;
304
      // running = true;
305
      switch(global.lfStrategy){
306
      case msg_content::MSG_START:
307
        newState = states::CALIBRATION_CHECK;
308
        break;
309
      case msg_content::MSG_STOP:
310
        newState = states::IDLE;
311
        break;
312
      case msg_content::MSG_EDGE_RIGHT:
313
        // newState = states::FOLLOW_LINE;
314
        lStrategy = LineFollowStrategy::EDGE_RIGHT;
315
        break;
316
      case  msg_content::MSG_EDGE_LEFT:
317
        // newState = states::FOLLOW_LINE;
318
        lStrategy = LineFollowStrategy::EDGE_LEFT;
319
        break;
320
      case msg_content::MSG_FUZZY:
321
        // newState = states::FOLLOW_LINE;
322
        lStrategy = LineFollowStrategy::FUZZY;
323
        break;
324
      case msg_content::MSG_DOCK:
325
        newState = states::DETECT_STATION;
326
        break;
327
      case msg_content::MSG_UNDOCK:
328
        newState = states::RELEASE;
329
        break;
330
      case msg_content::MSG_CHARGE:
331
        newState = states::CHARGING;
332
        break;
333
      case msg_content::MSG_RESET_ODOMETRY:
334
        global.odometry.resetPosition();
335
        break;
336
      case msg_content::MSG_CALIBRATE_BLACK:
337
        proxCalib.calibrateBlack = true;
338
        // global.odometry.resetPosition();
339
        newState = states::CALIBRATION;
340
        break;
341
      case msg_content::MSG_CALIBRATE_WHITE:
342
        proxCalib.calibrateBlack = false;
343
        newState = states::CALIBRATION;
344
        break;
345
      case msg_content::MSG_TEST_MAP_STATE:
346
        newState = states::TEST_MAP_STATE;
347
        break;
348

    
349
      default:
350
        newState = states::IDLE;
351
        break;
352
      }
353
    }
354
    // newState = currentState;
355

    
356
    // Get sensor data
357
    // uint16_t WL = global.vcnl4020[constants::DiWheelDrive::PROX_WHEEL_LEFT].getProximityScaledWoOffset();
358
    // uint16_t WR = global.vcnl4020[constants::DiWheelDrive::PROX_WHEEL_RIGHT].getProximityScaledWoOffset();
359
    for(int i=0; i<8;i++){
360
      rProx[i] = global.robot.getProximityRingValue(i);
361
    }
362

    
363
    // Continously update devication values
364
    meanDeviation(rProx[0] & 0xFFF0, rProx[7] & 0xFFF0);
365
    // int FL = global.vcnl4020[constants::DiWheelDrive::PROX_FRONT_LEFT].getProximityScaledWoOffset();
366
    // int FR = global.vcnl4020[constants::DiWheelDrive::PROX_FRONT_RIGHT].getProximityScaledWoOffset();
367
    switch(currentState){
368
      case states::INACTIVE:
369
        // Dummy state to deactivate every interaction
370
      break;
371
      // ---------------------------------------
372
      case states::CALIBRATION_CHECK:
373
        // global.robot.calibrate();
374
        if(global.linePID.BThresh >= global.linePID.WThresh){
375
          newState = states::CALIBRATION_ERROR;
376
        }