Revision 9c46b728

View differences:

devices/DiWheelDrive/DiWheelDrive.cpp
3 3
#include "qei.h"
4 4
#include "DiWheelDrive.h"
5 5

  
6

  
6 7
#include <global.hpp>
7 8

  
8 9
using namespace chibios_rt;
......
98 99
      }
99 100
      break;
100 101
    case CAN::SET_LINE_FOLLOW_SPEED:
101
	  if (frame->DLC == 8) {
102
		  uint8_t speedForward    = frame->data8[0];
103
		  uint8_t speedSoftLeft0  = frame->data8[1];
104
		  uint8_t speedSoftLeft1  = frame->data8[2];
105
		  uint8_t speedHardLeft0  = frame->data8[3];
106
		  uint8_t speedHardLeft1  = frame->data8[4];
107
		  global.rpmForward[0] = speedForward;
108
		  global.rpmForward[1] = speedForward;
109
		  global.rpmSoftLeft[0] = speedSoftLeft0;
110
		  global.rpmSoftLeft[1] = speedSoftLeft1;
111
		  global.rpmHardLeft[0] = speedHardLeft0;
112
		  global.rpmHardLeft[1] = speedHardLeft1;
113
		  global.rpmSoftRight[0] = global.rpmSoftLeft[1];
114
		  global.rpmSoftRight[1] = global.rpmSoftLeft[0];
115
		  global.rpmHardRight[0] = global.rpmHardLeft[1];
116
		  global.rpmHardRight[1] = global.rpmHardLeft[0];
117
		  return RDY_OK;
118
	  }
102
      if (frame->DLC == 8) {
103
        uint8_t speedForward    = frame->data8[0];
104
        uint8_t speedSoftLeft0  = frame->data8[1];
105
        uint8_t speedSoftLeft1  = frame->data8[2];
106
        uint8_t speedHardLeft0  = frame->data8[3];
107
        uint8_t speedHardLeft1  = frame->data8[4];
108
        global.rpmForward[0] = speedForward;
109
        global.rpmForward[1] = speedForward;
110
        global.rpmSoftLeft[0] = speedSoftLeft0;
111
        global.rpmSoftLeft[1] = speedSoftLeft1;
112
        global.rpmHardLeft[0] = speedHardLeft0;
113
        global.rpmHardLeft[1] = speedHardLeft1;
114
        global.rpmSoftRight[0] = global.rpmSoftLeft[1];
115
        global.rpmSoftRight[1] = global.rpmSoftLeft[0];
116
        global.rpmHardRight[0] = global.rpmHardLeft[1];
117
        global.rpmHardRight[1] = global.rpmHardLeft[0];
118
        return RDY_OK;
119
      }
120
      break;
121
    case CAN::SET_LINE_FOLLOW_STRATEGY:
122
      if (frame->DLC == 1) {
123
        global.lfStrategy = frame->data8[0];
124
        return RDY_OK;
125
      }
126
      break;
119 127
    case CAN::SET_KINEMATIC_CONST_ID:
120 128
      if (frame->DLC == 8) {
121 129
/*        // Set (but do not store) Ed
devices/DiWheelDrive/global.hpp
28 28
#include <DiWheelDrive.h>
29 29
#include <userthread.hpp>
30 30

  
31

  
31 32
using namespace amiro;
32 33

  
33 34
class Global final
......
163 164

  
164 165
  DiWheelDrive robot;
165 166

  
167

  
168

  
166 169
  UserThread userThread;
167 170
  int rpmForward[2] = {20,20};
168 171
  int rpmSoftLeft[2] = {10,20};
......
189 192

  
190 193
// Struct for saving motor gains
191 194

  
192
int resetProtect = 1;
193
motorGains motorConfigGains;
194
motorGains stopGains;
195
  int resetProtect = 1;
196
  motorGains motorConfigGains;
197
  motorGains stopGains;
198

  
199
  types::position startPos;
200
  types::position endPos;
195 201

  
196
types::position startPos;
197
types::position endPos;
202
  // Line Following strategy
203
  // 0 EDGE_RIGHT
204
  // 1 EDGE_LEFT
205
  // 2 FUZZY
206
  // 3 DOCKING
207
  int lfStrategy = 3;
198 208

  
199 209
// Debugging stuff --------------
200 210
  int forwardSpeed = 10;
devices/DiWheelDrive/linefollow2.hpp
2 2
#define AMIRO_LINEFOLLOWING_H
3 3

  
4 4
#include <ch.hpp>
5

  
5
#include "global.hpp"
6 6
#include <amiroosconf.h>
7 7

  
8 8
namespace amiro {
9
  
9 10
  enum class LineFollowStrategy{
10 11
  EDGE_LEFT,
11 12
  EDGE_RIGHT,
12 13
  DOCKING,
13 14
  MIDDLE,
14
  FUZZY
15
};
15
  FUZZY,
16
  NONE
17
  };
16 18

  
17 19
enum colorMember : uint8_t {
18 20
	BLACK=0,
devices/DiWheelDrive/main.cpp
1160 1160
  
1161 1161
}
1162 1162

  
1163
void enableCharging(){
1164
  global.ltc4412.enable(true);
1165
}
1163 1166

  
1164
void getAccel(BaseSequentialStream *chp, int argc, char *argv[]){
1165
  int steps = 0;
1166
  // global.motorcontrol.getGains(&global.motorConfigGains);
1167
  // global.motorcontrol.setGains(&global.stopGains);
1168
  int16_t time = 10000;
1169
  int32_t angle = 3141592;
1170
  int32_t distance = 0;
1171
  if (argc == 1){
1172
    chprintf(chp, "%i steps \n", atoi(argv[0]));
1173
    steps = atoi(argv[0]);
1174
  }
1175
  else if(argc == 3){
1176
    distance = atoi(argv[0]);
1177
    angle = atoi(argv[0]);
1178
    time = atoi(argv[0]);
1179
  }else{
1180
    chprintf(chp, "Use: accel <steps>\n");
1181
    return;
1182
  }
1183
  global.distcontrol.setTargetPosition(distance, angle, time);
1167
void disableCharging(){
1168
  global.ltc4412.enable(false);
1169
}
1184 1170

  
1185
  for(int i=0; i<steps; i++){
1186
    int16_t Z = global.lis331dlh.getAccelerationForce(LIS331DLH::AXIS_Z);
1187
    int16_t X = global.lis331dlh.getAccelerationForce(LIS331DLH::AXIS_X);
1188
    int16_t Y = global.lis331dlh.getAccelerationForce(LIS331DLH::AXIS_Y);
1189
    types::position pos = global.odometry.getPosition();
1190
    // chprintf((BaseSequentialStream*)&global.sercanmux1, "Axis X: %d, Y: %d, Z: %d\n", X, Y, Z);
1191
    chprintf((BaseSequentialStream*)&global.sercanmux1, "Position X: %d, Y: %d,  Rotation X: %d, Y: %d, Z: %d, Angle: %d\n", pos.x, pos.y, pos.f_x, pos.f_y, pos.f_z, global.distcontrol.getCurrentTargetAngle());
1192
    // chprintf((BaseSequentialStream*)&global.sercanmux1, "Position X: %d, Y: %d, Z: %d\n", pos.f_x, pos.f_y, pos.f_z);
1193
    BaseThread::sleep(CAN::UPDATE_PERIOD);
1194
  }
1195 1171

  
1196
  // global.motorcontrol.setGains(&global.motorConfigGains);
1172
void setGlobalStrategy(BaseSequentialStream *chp, int argc, char *argv[]){
1173
  if(argc == 1){
1174
  
1175
    global.lfStrategy = atoi(argv[0]); 
1176
  }
1197 1177
}
1198 1178

  
1199 1179
void getPosition(BaseSequentialStream *chp, int argc, char *argv[]){
......
1210 1190
  }
1211 1191
}
1212 1192

  
1193
// TODO: Not wokring, either loading station has no power or logic not working
1194
void checkPower(BaseSequentialStream *chp, int argc, char *argv[]){
1195
  int steps = 2000;
1196
  int led = 0;
1197
  enableCharging();
1198
  for (int i=0; i<steps;i++){
1199
    chprintf(chp, "%s Enable: %s\n", global.ltc4412.isPluggedIn() ? "y" : "n", global.ltc4412.isEnabled() ? "y2" : "n2"); 
1200
    if(global.ltc4412.isPluggedIn()){
1201
      // enableCharging();
1202
      for(led=0; led<8; led++){
1203
        global.robot.setLightColor(led, Color(Color::GREEN));
1204
      }
1205
    }else{
1206
      // disableCharging();
1207
      for(led=0; led<8; led++){
1208
        global.robot.setLightColor(led, Color(Color::RED));
1209
      }
1210
    }
1211
    BaseThread::sleep(CAN::UPDATE_PERIOD);
1212
  }
1213
  disableCharging();
1214
  for(led=0; led<8; led++){
1215
    global.robot.setLightColor(led, Color(Color::BLACK));
1216
  }
1217
}
1218

  
1219

  
1213 1220
static const ShellCommand commands[] = {
1214 1221
  {"shutdown", shellRequestShutdown},
1215 1222
  {"wakeup", shellRequestWakeup},
......
1249 1256
  {"followLine", followLine},
1250 1257
  {"rotate", rotate},
1251 1258
  {"followRotate", followAndRotate},
1252
  {"accel", getAccel},
1253 1259
  {"getPos", getPosition},
1260
  {"checkPower", checkPower},
1261
  {"setStrategy", setGlobalStrategy},
1254 1262
  {NULL, NULL}
1255 1263
};
1256 1264

  
devices/DiWheelDrive/userthread.cpp
42 42
      }
43 43
}
44 44

  
45
/**
46
 * Get the wanted strategy from the global object.
47
 */
48
LineFollowStrategy determineStrategy(){
49
  switch(global.lfStrategy){
50
    case 0:
51
      return LineFollowStrategy::EDGE_RIGHT;
52
      break;
53
    case 1:
54
      return LineFollowStrategy::EDGE_LEFT;
55
      break;
56
    case 2:
57
      return LineFollowStrategy::FUZZY;
58
      break;
59
    case 3:
60
      return LineFollowStrategy::DOCKING;
61
    default:
62
      break;
63
  }
64
  return LineFollowStrategy::NONE;
65
}
66

  
67
/**
68
 * Blocks as long as the position changes.
69
 */
70
void checkForMotion(UserThread *ut){
71
  int motion = 1;
72
  int led = 0;
73
  types::position oldPos = global.odometry.getPosition();
74
  while(motion){
75
    ut->sleep(500);
76
    types::position tmp = global.odometry.getPosition();
77
    motion = abs(oldPos.x - tmp.x)+ abs(oldPos.y - tmp.y)+abs(oldPos.z - tmp.z);
78
    oldPos = tmp;
79
      global.robot.setLightColor((led + 1) % 8, Color(Color::YELLOW));
80
      global.robot.setLightColor(led % 8, Color(Color::BLACK));
81
      led++;
82
  }
83
}
84

  
85

  
86
/**
87
 * Turns MotorControl off and checks if position remains stable.
88
 */
89
int checkDockingSuccess(UserThread *ut){
90
  // global.motorcontrol.setTargetRPM(0,0);
91
  checkForMotion(ut);
92
  int led = 0;
93
  int success = 0;
94
  global.odometry.resetPosition();
95
  types::position start = global.startPos = global.odometry.getPosition();
96
  global.motorcontrol.toggleMotorEnable();
97
  ut->sleep(1000);
98
  types::position stop = global.endPos = global.odometry.getPosition();
99
  global.motorcontrol.toggleMotorEnable();
100
  // Amiro moved, docking was not successful
101
  if ((start.x + stop.x) || (start.y + stop.y)){
102
    for(led=0; led<8; led++){
103
      global.robot.setLightColor(led, Color(Color::RED));
104
    }
105
    success = 0;
106
  }else{
107
    for(led=0; led<8; led++){
108
      global.robot.setLightColor(led, Color(Color::GREEN));
109
    }
110
    success = 1;
111
  }
112
  
113
  ut->sleep(500);
114
  for(led=0; led<8; led++){
115
          global.robot.setLightColor(led, Color(Color::BLACK));
116
  }
117
  return success;
118
}
119

  
120
void correctPosition(UserThread *ut, LineFollow &lf, int steps){
121
  int checkWhite = 0;
122
  int rpmSpeed[2] ={0};
123
  lf.setStrategy(LineFollowStrategy::EDGE_LEFT);
124
  for (int correction=0; correction<steps; correction++){
125
    checkWhite = lf.followLine(rpmSpeed);
126
    setRpmSpeed(rpmSpeed);
127
    ut->sleep(CAN::UPDATE_PERIOD);
128
  }
129
}
45 130

  
46 131

  
47 132
UserThread::UserThread() :
......
59 144
  /*
60 145
   * SETUP
61 146
   */
62
  int rpmFuzzyCtrl[2] = {0};
147
  int rpmSpeed[2] = {0};
148
  int stop[2] = {0};
149
  int proxyWheelThresh = 18000;
63 150
  for (uint8_t led = 0; led < 8; ++led) {
64 151
    global.robot.setLightColor(led, Color(Color::BLACK));
65 152
  }
......
99 186
        running = !running;
100 187
    }
101 188
    if(running){
189
      switch(utState){
190
        case states::FOLLOW_LINE:{
191
          LineFollowStrategy lStrategy = determineStrategy();
192
          if(lStrategy == LineFollowStrategy::DOCKING){
193
            utState = states::OCCUPY;
194
            break;
195
          }
196
          lf.setStrategy(lStrategy);
197
          lf.followLine(rpmSpeed);
198
          setRpmSpeed(rpmSpeed);
199
          break;
200
        }
201
        case states::OCCUPY:{
202
          // Get Wheel proxy sensors
203
          int WL = global.vcnl4020[constants::DiWheelDrive::PROX_WHEEL_LEFT].getProximityScaledWoOffset();
204
          int WR = global.vcnl4020[constants::DiWheelDrive::PROX_WHEEL_LEFT].getProximityScaledWoOffset();
205
          // Check for black
206
          if ((WL+WR) < proxyWheelThresh){ /*TODO: Only check for one sensor */
207
            global.motorcontrol.setTargetRPM(0,0);
102 208

  
103
    }
209
            // Stop when in docking state and take further actions
210
            if(lf.getStrategy() == LineFollowStrategy::DOCKING){
211
              if(checkDockingSuccess(this)){
212
                utState = states::CHARGING;
213
                break;
214
              }else{
215
                correctPosition(this, lf, 250);
216
                lf.setStrategy(LineFollowStrategy::DOCKING);
217
                // break;
218
              }
219
            }else{
220
              checkForMotion(this);
221
              // 180° Rotation 
222
              global.distcontrol.setTargetPosition(0, 3141592, 10000);
223
              // BaseThread::sleep(8000);
224
              checkForMotion(this);
225
              correctPosition(this, lf, 250);
226
              // break;
227
              lf.setStrategy(LineFollowStrategy::DOCKING);
228
              
229
            }
230
          }
231

  
232
          // Set correct following
233
          lf.setStrategy(LineFollowStrategy::EDGE_RIGHT);
234
          lf.followLine(rpmSpeed);
235
          setRpmSpeed(rpmSpeed);
236
          
237
          break;
238
        }
239
        case states::RELEASE:{
240
          break;
241
        }
242
        case states::CHARGING:{
243
          break;
244
        }
245
        default:{
246
          break;
247
        }
248
      }
249

  
250
    }else{
251
      // Stop
252
        setRpmSpeed(stop);
253
      }
104 254

  
105
      lf.followLine(rpmFuzzyCtrl);
106
            setRpmSpeed(rpmFuzzyCtrl);
107
    // this->sleep(US2ST(5));
108 255
    this->sleep(CAN::UPDATE_PERIOD);
109 256
  }
110 257

  

Also available in: Unified diff