Statistics
| Branch: | Tag: | Revision:

amiro-os / devices / DiWheelDrive / userthread.cpp @ d314ad6f

History | View | Annotate | Download (9.422 KB)

1 58fe0e0b Thomas Schöpping
#include "userthread.hpp"
2
#include "global.hpp"
3 c76baf23 Georg Alberding
#include "linefollow2.hpp" 
4
5 58fe0e0b Thomas Schöpping
using namespace amiro;
6
7
extern Global global;
8
9
// a buffer for the z-value of the accelerometer
10
int16_t accel_z;
11 5d138bca galberding
bool running = false;
12 58fe0e0b Thomas Schöpping
13
14 181f2892 galberding
/**
15
 * Set speed.
16
 * 
17
 * @param rpmSpeed speed for left and right wheel in rounds/min
18
 */
19
void UserThread::setRpmSpeed(const int (&rpmSpeed)[2]) {
20 5d138bca galberding
  global.motorcontrol.setTargetRPM(rpmSpeed[constants::DiWheelDrive::LEFT_WHEEL] * 1000000, rpmSpeed[constants::DiWheelDrive::RIGHT_WHEEL] * 1000000);
21 58fe0e0b Thomas Schöpping
}
22
23 181f2892 galberding
void UserThread::lightOneLed(Color color, int idx){
24 5d138bca galberding
  global.robot.setLightColor(idx, Color(color));
25
}
26 58fe0e0b Thomas Schöpping
27 181f2892 galberding
void UserThread::lightAllLeds(Color color){
28 5d138bca galberding
  int led = 0;
29
  for(led=0; led<8; led++){
30
        lightOneLed(color, led);
31
      }
32 58fe0e0b Thomas Schöpping
}
33
34 181f2892 galberding
void UserThread::showChargingState(){
35
  uint8_t numLeds = global.robot.getPowerStatus().state_of_charge / 12;
36
  Color color = Color::GREEN;
37
  if (numLeds <= 2){
38
    color = Color::RED;
39
  }else if(numLeds <= 6){
40
    color = Color::YELLOW;
41
  }
42
  for (int i=0; i<numLeds; i++){
43
    lightOneLed(color, i);
44
    this->sleep(300);
45 9c46b728 galberding
  }
46 181f2892 galberding
  this->sleep(1000);
47
  lightAllLeds(Color::BLACK);
48 9c46b728 galberding
}
49
50
/**
51
 * Blocks as long as the position changes.
52
 */
53 181f2892 galberding
void UserThread::checkForMotion(){
54 9c46b728 galberding
  int motion = 1;
55
  int led = 0;
56
  types::position oldPos = global.odometry.getPosition();
57
  while(motion){
58 181f2892 galberding
    this->sleep(500);
59 9c46b728 galberding
    types::position tmp = global.odometry.getPosition();
60
    motion = abs(oldPos.x - tmp.x)+ abs(oldPos.y - tmp.y)+abs(oldPos.z - tmp.z);
61
    oldPos = tmp;
62
      global.robot.setLightColor((led + 1) % 8, Color(Color::YELLOW));
63
      global.robot.setLightColor(led % 8, Color(Color::BLACK));
64
      led++;
65
  }
66
}
67
68 181f2892 galberding
bool UserThread::checkPinVoltage(){
69
  return global.ltc4412.isPluggedIn(); 
70
}
71 9c46b728 galberding
72 181f2892 galberding
bool UserThread::checkPinEnabled(){
73
  return global.ltc4412.isEnabled();
74
}
75
76
int UserThread::checkDockingSuccess(){
77
  // setRpmSpeed(stop);
78
  checkForMotion();
79 9c46b728 galberding
  int success = 0;
80
  global.odometry.resetPosition();
81
  types::position start = global.startPos = global.odometry.getPosition();
82
  global.motorcontrol.toggleMotorEnable();
83 181f2892 galberding
  this->sleep(1000);
84
  types::position stop_ = global.endPos = global.odometry.getPosition();
85
  
86 9c46b728 galberding
  // Amiro moved, docking was not successful
87 181f2892 galberding
  if ((start.x + stop_.x) || (start.y + stop_.y)){
88
    lightAllLeds(Color::RED);
89
    // Enable Motor again if docking was not successful
90
    global.motorcontrol.toggleMotorEnable();
91 9c46b728 galberding
    success = 0;
92
  }else{
93 181f2892 galberding
    lightAllLeds(Color::GREEN);
94 9c46b728 galberding
    success = 1;
95
  }
96
  
97 181f2892 galberding
  this->sleep(500);
98
  lightAllLeds(Color::BLACK);
99 9c46b728 galberding
  return success;
100
}
101
102 58fe0e0b Thomas Schöpping
UserThread::UserThread() :
103
  chibios_rt::BaseStaticThread<USER_THREAD_STACK_SIZE>()
104
{
105
}
106
107
UserThread::~UserThread()
108
{
109
}
110
111
msg_t
112
UserThread::main()
113
{
114 5d138bca galberding
  /*
115
   * SETUP
116
   */
117 181f2892 galberding
  // User thread state:
118
states utState = states::IDLE;
119
states newState;
120
121
   int whiteBuf = 0;
122
   int correctionStep = 0;
123 9c46b728 galberding
  int rpmSpeed[2] = {0};
124
  int stop[2] = {0};
125 181f2892 galberding
  LineFollowStrategy lStrategy = LineFollowStrategy::FUZZY;
126 5d138bca galberding
  for (uint8_t led = 0; led < 8; ++led) {
127
    global.robot.setLightColor(led, Color(Color::BLACK));
128
  }
129
  running = false;
130
  LineFollow lf(&global);
131
  /*
132
   * LOOP
133
   */
134
  while (!this->shouldTerminate())
135
  {
136 181f2892 galberding
    /*
137
    * read accelerometer z-value
138
    */
139
    accel_z = global.lis331dlh.getAccelerationForce(LIS331DLH::AXIS_Z);
140
        
141
    if (accel_z < -900 /*-0.9g*/) { 
142
      // Start line following when AMiRo is rotated
143
      if(utState == states::IDLE){
144
        utState = states::FOLLOW_LINE;
145
      }else{
146
        utState = states::IDLE;
147
      }
148
      lightAllLeds(Color::GREEN);
149
      this->sleep(1000);
150
      lightAllLeds(Color::BLACK);
151 c76baf23 Georg Alberding
152 d607fcef galberding
    // If message was received handle it here:
153
    } else if(global.msgReceived){
154
      global.msgReceived = false;
155 181f2892 galberding
      // running = true;
156 d607fcef galberding
      switch(global.lfStrategy){
157
        case msg_content::START:
158 181f2892 galberding
          utState = states::FOLLOW_LINE;
159 d607fcef galberding
          break;
160
        case msg_content::STOP:
161 181f2892 galberding
          utState = states::IDLE;
162 d607fcef galberding
          break;
163
        case msg_content::EDGE_RIGHT:
164 181f2892 galberding
          // utState = states::FOLLOW_LINE;
165 d607fcef galberding
          lStrategy = LineFollowStrategy::EDGE_RIGHT;
166
          break;
167
        case  msg_content::EDGE_LEFT:
168 181f2892 galberding
          // utState = states::FOLLOW_LINE;
169 d607fcef galberding
          lStrategy = LineFollowStrategy::EDGE_LEFT;
170
          break;
171
        case msg_content::FUZZY:
172 181f2892 galberding
          // utState = states::FOLLOW_LINE;
173 d607fcef galberding
          lStrategy = LineFollowStrategy::FUZZY;
174
          break;
175 181f2892 galberding
        case msg_content::DOCK:
176
          utState = states::DETECT_STATION;
177
          break;
178
        case msg_content::UNDOCK:
179
          utState = states::RELEASE;
180
          break;
181
        case msg_content::CHARGE:
182
          utState = states::CHARGING;
183 d607fcef galberding
          break;
184
        default:
185 181f2892 galberding
          utState = states::IDLE;
186 d607fcef galberding
          break;
187
      }
188 5d138bca galberding
    }
189 181f2892 galberding
    newState = utState;
190 d607fcef galberding
191 181f2892 galberding
    // Get sensor data 
192
    int WL = global.vcnl4020[constants::DiWheelDrive::PROX_WHEEL_LEFT].getProximityScaledWoOffset();
193
    int WR = global.vcnl4020[constants::DiWheelDrive::PROX_WHEEL_RIGHT].getProximityScaledWoOffset();
194
    // int FL = global.vcnl4020[constants::DiWheelDrive::PROX_FRONT_LEFT].getProximityScaledWoOffset();
195
    // int FR = global.vcnl4020[constants::DiWheelDrive::PROX_FRONT_RIGHT].getProximityScaledWoOffset();
196
    switch(utState){
197
      case states::IDLE:
198
        if (!global.motorcontrol.getMotorEnable()){
199
            global.motorcontrol.toggleMotorEnable();
200
        }
201
        setRpmSpeed(stop);
202
        if(/* checkPinVoltage() && */ checkPinEnabled()){
203
          global.robot.requestCharging(0);
204
        }
205
        
206
        break;
207
      // ---------------------------------------
208
      case states::FOLLOW_LINE:
209
      // Set correct forward speed to every strategy
210
        if (global.forwardSpeed != global.rpmForward[0]){
211
          global.forwardSpeed = global.rpmForward[0];
212
        }
213
        
214
        if(lf.getStrategy() != lStrategy){
215 9c46b728 galberding
          lf.setStrategy(lStrategy);
216
        }
217 5d138bca galberding
218 181f2892 galberding
        //TODO: Check if white is detected and stop threshold is reached
219
        if(lf.followLine(rpmSpeed)){
220
          
221
          if(whiteBuf >= WHITE_COUNT_THRESH){
222
            setRpmSpeed(stop);
223
            newState = states::IDLE;
224
          }else{
225
            whiteBuf++;
226 9c46b728 galberding
          }
227 181f2892 galberding
        }else{
228
          whiteBuf = 0;
229 9c46b728 galberding
          setRpmSpeed(rpmSpeed);
230
        }
231 181f2892 galberding
        // lf.followLine(rpmSpeed);
232
        // setRpmSpeed(rpmSpeed);
233
        
234
        break;
235
      // ---------------------------------------
236
      case states::DETECT_STATION:
237
        if (global.forwardSpeed != CHARGING_SPEED){
238
          global.forwardSpeed = CHARGING_SPEED;
239 9c46b728 galberding
        }
240 181f2892 galberding
        if(lf.getStrategy() != LineFollowStrategy::EDGE_RIGHT){
241
          lf.setStrategy(LineFollowStrategy::EDGE_RIGHT);
242
        }
243
244
        lf.followLine(rpmSpeed);
245
        setRpmSpeed(rpmSpeed);
246
        // // Detect marker before docking station
247
        if ((WL+WR) < PROXY_WHEEL_THRESH){
248 d607fcef galberding
          setRpmSpeed(stop);
249 181f2892 galberding
          checkForMotion();
250
          // 180° Rotation 
251
          global.distcontrol.setTargetPosition(0, ROTATION_180, ROTATION_DURATION);
252
          // BaseThread::sleep(8000);
253
          checkForMotion();
254
          newState = states::CORRECT_POSITIONING;
255 9c46b728 galberding
        }
256 181f2892 galberding
        break;
257
      // ---------------------------------------
258
      case states::CORRECT_POSITIONING:
259
        if(lf.getStrategy() != LineFollowStrategy::EDGE_LEFT){
260
          lf.promptStrategyChange(LineFollowStrategy::EDGE_LEFT);
261 9c46b728 galberding
        }
262 181f2892 galberding
        lf.followLine(rpmSpeed);
263
        setRpmSpeed(rpmSpeed);
264 9c46b728 galberding
265 181f2892 galberding
        correctionStep++;
266
        if (correctionStep >= MAX_CORRECTION_STEPS){
267
          correctionStep = 0;
268
          newState = states::REVERSE;
269
          setRpmSpeed(stop);
270
          checkForMotion();
271
        }
272
        break;
273
      // ---------------------------------------
274
      case states::REVERSE:
275
        if(lf.getStrategy() != LineFollowStrategy::REVERSE){
276
          lf.setStrategy(LineFollowStrategy::REVERSE);
277
        }
278
        lf.followLine(rpmSpeed);
279
        setRpmSpeed(rpmSpeed);
280 58fe0e0b Thomas Schöpping
281 181f2892 galberding
        if ((WL+WR) < PROXY_WHEEL_THRESH){
282
          setRpmSpeed(stop);
283
          checkForMotion();
284
          newState = states::CHECK_POSITIONING;
285
        }
286
        break;
287
      // ---------------------------------------
288
      case states::CHECK_POSITIONING:
289
        if(checkDockingSuccess()/* && checkVoltage() */){
290
          newState = states::CHARGING;
291
        }else{
292
          newState = states::CORRECT_POSITIONING;
293
        }
294
        break;
295
      // ---------------------------------------
296
      case states::CHARGING:
297
        if (global.motorcontrol.getMotorEnable()){
298
          global.motorcontrol.toggleMotorEnable();
299
        }
300
        // Formulate Request to enable charging
301
        if(/* checkPinVoltage() && */ !checkPinEnabled()){
302
          global.robot.requestCharging(1);
303
        }
304
        if(checkPinEnabled()){
305
          showChargingState();
306
        }
307
        break;
308
      
309
      // ---------------------------------------
310
      case states::RELEASE:
311
        if(/* checkPinVoltage() && */ checkPinEnabled()){
312
          global.robot.requestCharging(0);
313
        }
314
315
        if(checkPinEnabled()){
316
          showChargingState();
317
        }else{
318
          if (!global.motorcontrol.getMotorEnable()){
319
            global.motorcontrol.toggleMotorEnable();
320
          }
321
          //Rotate -20° to free from magnet
322
          global.distcontrol.setTargetPosition(0, ROTATION_20, ROTATION_DURATION);
323
          checkForMotion();
324
          lStrategy = LineFollowStrategy::EDGE_RIGHT;
325
          newState = states::FOLLOW_LINE;
326
        }
327
        lightAllLeds(Color::BLACK);
328
        break;
329
      
330
      default:
331
        break;
332
      }
333
      utState = newState;
334 5d138bca galberding
    this->sleep(CAN::UPDATE_PERIOD);
335
  }
336 58fe0e0b Thomas Schöpping
337
  return RDY_OK;
338
}