Revision 22b85da1

View differences:

devices/DiWheelDrive/global.hpp
169 169
  int rpmHardLeft[2] = {5,20};
170 170
  int rpmSoftRight[2] = {rpmSoftLeft[1],rpmSoftLeft[0]};
171 171
  int rpmHardRight[2] = {rpmHardLeft[1],rpmHardLeft[0]};
172
  
172 173

  
173 174
  // Line Following thresholds set due to calibration
174 175
  // MaxDelta: 18676, FL: 4289, FR: 22965
175
  int threshProxyL = 2168;
176
  int threshProxyR = 24406;
176
  // Thresh FL: 5241, FR: 25528
177
  int threshProxyL = 5241;
178
  int threshProxyR = 25528;
179
  int threshWhite = 78000;
180

  
181
  // PID for line following:
182
  float K_p = 0.0f;
183
  float K_i = 0.0f;
184
  float K_d = 0.0f;
185

  
186
  // Integral part
187
  int accumHist = 0;
188
  int oldError = 0;
189

  
190
// Debugging stuff --------------
191
  int forwardSpeed = 10;
192
  int enableRecord = 0;
177 193

  
178 194
  // Buffer for sensor values
179 195
  struct sensorRecord
......
186 202
  
187 203
  int sensSamples = 0;
188 204
  sensorRecord senseRec[1000];
205
  sensorRecord maxDist;
189 206
  
190

  
207
// -----------------------------
191 208
public:
192 209
  Global() :
193 210
    HW_I2C1(&I2CD1), HW_I2C2(&I2CD2),
devices/DiWheelDrive/linefollow2.cpp
2 2
#include "linefollow2.hpp" 
3 3
#include <cmath>
4 4

  
5

  
5
// Trash
6 6
void LineFollow::printSensorData(){
7 7
    chprintf((BaseSequentialStream*) &SD1, "Test!");
8 8
}
9 9

  
10

  
10 11
LineFollow::LineFollow(Global *global){
11 12
    this->global = global;
12 13
}
13 14

  
15
// trash
14 16
int LineFollow::delta(){
15 17
    int delta = 0;
16 18
    int FL = global->vcnl4020[constants::DiWheelDrive::PROX_FRONT_LEFT].getProximityScaledWoOffset();
......
26 28
    return  delta;
27 29
}
28 30

  
29

  
31
// old and trash
30 32
void LineFollow::stableFollow(int vcnl4020Proximity[4], int (&rpmFuzzyCtrl)[2], Global *global){
31 33
    int targetSensor = 0x38;
32 34
    int actualSensorL = vcnl4020Proximity[constants::DiWheelDrive::PROX_FRONT_LEFT] ;
......
53 55

  
54 56
}
55 57

  
56
int error(){
58
/**
59
 * Calculate the error from front proxi sensors and fixed threshold values for those sensors.
60
 */
61
int LineFollow::getError(){
62
    
57 63
    int FL = global->vcnl4020[constants::DiWheelDrive::PROX_FRONT_LEFT].getProximityScaledWoOffset();
58 64
    int FR = global->vcnl4020[constants::DiWheelDrive::PROX_FRONT_RIGHT].getProximityScaledWoOffset();
59 65
    int targetL = global->threshProxyL;
60 66
    int targetR = global->threshProxyR;
61
    return FL -targetL + FR - targetR;
67
    int error = FL -targetL + FR - targetR;
68

  
69
    if (FL+FR > global->threshWhite){
70
        whiteFlag = 1;
71
    }else{
72
        whiteFlag = 0;
73
    }
74
    return error;
75
}
76

  
77
/**
78
 * Follow strategy for left edge. 
79
 */
80
int LineFollow::followLeftEdge(int rpmSpeed[2]){
81

  
82
    int correctionSpeed = getPidCorrectionSpeed();
83
    chprintf((BaseSequentialStream*) &SD1, "Correction: %d, thresh: %d\n",correctionSpeed,  global->threshWhite);
84

  
85
    rpmSpeed[constants::DiWheelDrive::LEFT_WHEEL] =   global->forwardSpeed + correctionSpeed;
86

  
87
    rpmSpeed[constants::DiWheelDrive::RIGHT_WHEEL] = global->forwardSpeed - correctionSpeed;
88
    return whiteFlag;
89
}
90

  
91
/**
92
 * Follow strategy for right edge. 
93
 */
94
int LineFollow::followRightEdge(int rpmSpeed[2]){
95

  
96
    int correctionSpeed = getPidCorrectionSpeed();
97
    chprintf((BaseSequentialStream*) &SD1, "Correction: %d, thresh: %d\n",correctionSpeed,  global->threshWhite);
98

  
99
    rpmSpeed[constants::DiWheelDrive::LEFT_WHEEL] =   global->forwardSpeed - correctionSpeed;
100

  
101
    rpmSpeed[constants::DiWheelDrive::RIGHT_WHEEL] = global->forwardSpeed + correctionSpeed;
102
    return whiteFlag;
103
}
104

  
105
/**
106
 * Pid controller which returns a corrections speed.
107
 */
108
int LineFollow::getPidCorrectionSpeed(){
109
    int error = getError();
110
    int sloap = error - global->oldError;
111
    int correctionSpeed = (int) (global->K_p*error + global->K_i*global->accumHist + global->K_d*sloap);
112
    global->oldError = error;
113
    global->accumHist += error;
114
    if (abs(error) > global->maxDist.error){
115
        global->maxDist.error = error;
116
    }
117
    return correctionSpeed;
62 118
}
63 119

  
64
void LineFollow::calibrateZiegler(float KCrit, int rpmSpeed[2]){
65
    int targetSpeedL = 5;
66
    int targetSpeedR = 5;
67
    int delta_ = error();
68
    int correctionSpeed = (int) (KCrit * delta_);   
69
    // global->senseRec[global->sensSamples].FL = FL;
70
    // global->senseRec[global->sensSamples].FR = FR;
71
    global->senseRec[global->sensSamples].error = delta_;
72
    global->senseRec[global->sensSamples].FL = global->vcnl4020[constants::DiWheelDrive::PROX_FRONT_LEFT].getProximityScaledWoOffset();;
73
    global->senseRec[global->sensSamples].FR = global->vcnl4020[constants::DiWheelDrive::PROX_FRONT_RIGHT].getProximityScaledWoOffset();;
74
    global->sensSamples++
75

  
76

  
77
    rpmSpeed[constants::DiWheelDrive::LEFT_WHEEL] =   -1*correctionSpeed;
78
    rpmSpeed[constants::DiWheelDrive::RIGHT_WHEEL] =  correctionSpeed;
79
    // chprintf((BaseSequentialStream*) &SD1, "CS:%d,LW:%d,RW:%d\n", correctionSpeed, rpmSpeed[constants::DiWheelDrive::LEFT_WHEEL], rpmSpeed[constants::DiWheelDrive::RIGHT_WHEEL]);
80
}
120
// trash
121
// void LineFollow::calibrateZiegler(float KCrit, int rpmSpeed[2]){
122
//     int targetSpeedL = 5;
123
//     int targetSpeedR = 5;
124
//     int delta_ = error();
125
//     int correctionSpeed = (int) (KCrit * delta_);   
126
//     if (global->enableRecord){
127
//         global->senseRec[global->sensSamples].error = delta_;
128
//         global->senseRec[global->sensSamples].FL = global->vcnl4020[constants::DiWheelDrive::PROX_FRONT_LEFT].getProximityScaledWoOffset();
129
//         global->senseRec[global->sensSamples].FR = global->vcnl4020[constants::DiWheelDrive::PROX_FRONT_RIGHT].getProximityScaledWoOffset();
130
//         global->sensSamples++;
131
//         }
132
//     if (abs(delta_) > global->maxDist.error){
133
//         global->maxDist.error = delta_;
134
//     }
135

  
136
//     rpmSpeed[constants::DiWheelDrive::LEFT_WHEEL] =   global->forwardSpeed + -1*correctionSpeed;
137
//     rpmSpeed[constants::DiWheelDrive::RIGHT_WHEEL] = global->forwardSpeed + correctionSpeed;
138
//     chprintf((BaseSequentialStream*) &SD1, "CS:%d,LW:%d,RW:%d\n", correctionSpeed, rpmSpeed[constants::DiWheelDrive::LEFT_WHEEL], rpmSpeed[constants::DiWheelDrive::RIGHT_WHEEL]);
139
// }
devices/DiWheelDrive/linefollow2.hpp
15 15
  float SetPoint = 0x4000; // (0x1800+0x2800) >> 8
16 16
  float Kp = 0.001;
17 17
  float Ki = 0.00001;
18
  float Kd = 0.5
19
  ;
18
  float Kd = 0.5;
20 19
  int accSum = 0;
21 20
  float oldError = 0;
22 21
  int biggestDiff = 0;
23 22
  Global *global;
24 23
  LineFollow(Global *global);
25
  void calibrateZiegler(float KCrit, int rpmSpeed[2]);
24
  // void calibrateZiegler(float KCrit, int rpmSpeed[2]);
25
  int followLeftEdge(int rpmSpeed[2]);
26
  int followRightEdge(int rpmSpeed[2]);
26 27

  
27 28
  private:
28 29
    int delta();
30
    int getError();
31
    int getPidCorrectionSpeed();
32

  
33
    char whiteFlag = 0;
34
    
29 35

  
30 36
};
31 37

  
devices/DiWheelDrive/main.cpp
708 708
    int proxyL = 0;
709 709
    int proxyR = 0;
710 710
    int maxDelta = 0;
711
    int sensorL = 0;
712
    int sensorR = 0;
711 713
 
712 714
  if (argc == 1){
713 715
    chprintf(chp, "Test %i rounds \n", atoi(argv[0]));
......
739 741
      proxyL = vcnl4020Proximity[constants::DiWheelDrive::PROX_FRONT_LEFT];
740 742
      proxyR = vcnl4020Proximity[constants::DiWheelDrive::PROX_FRONT_RIGHT];
741 743
    }
744
    sensorL += global.vcnl4020[constants::DiWheelDrive::PROX_FRONT_LEFT].getProximityScaledWoOffset();
745
    sensorR += global.vcnl4020[constants::DiWheelDrive::PROX_FRONT_RIGHT].getProximityScaledWoOffset();
742 746

  
743 747
    // if (vcnl4020Proximity[constants::DiWheelDrive::PROX_FRONT_RIGHT] > proxyR && vcnl4020Proximity[constants::DiWheelDrive::PROX_FRONT_LEFT] > proxyL ){
744 748
    //   delta *= -1;
......
754 758
    // sleep(CAN::UPDATE_PERIOD);
755 759
    BaseThread::sleep(CAN::UPDATE_PERIOD);
756 760
  }
757
  chprintf(chp,"Sensors Calibrated: MaxDelta: %d, FL: %d, FR: %d\n", maxDelta, proxyL, proxyR);
761
  
758 762

  
759
  global.threshProxyL = proxyL;
760
  global.threshProxyR = proxyR;
763
  global.threshProxyL = sensorL / rounds;
764
  global.threshProxyR = sensorR / rounds;
765
  chprintf(chp,"Thresh FL: %d, FR: %d\n",  global.threshProxyL, global.threshProxyR);
761 766
  return;
762 767
}
763 768

  
......
770 775
  uint16_t proxyL = global.threshProxyL;
771 776
  uint16_t proxyR = global.threshProxyR;
772 777
  uint16_t maxDelta = 0;
773
 
778
  
779
  int sensorL = 0;
780
  int sensorR = 0;
774 781
  if (argc == 1){
775 782
    chprintf(chp, "Test %i rounds \n", atoi(argv[0]));
776 783
    rounds = atoi(argv[0]);
......
783 790
        vcnl4020AmbientLight[i] = global.vcnl4020[i].getAmbientLight();
784 791
        vcnl4020Proximity[i] = global.vcnl4020[i].getProximityScaledWoOffset();
785 792
    }
786

  
793
    
787 794
    uint16_t delta = (vcnl4020Proximity[constants::DiWheelDrive::PROX_FRONT_LEFT]
788 795
                  - vcnl4020Proximity[constants::DiWheelDrive::PROX_FRONT_RIGHT]);
789 796
    // // Update proximity thresh
......
810 817
  return;
811 818
}
812 819

  
820
// Either 0 to disable record or > 0 to enable it
821
void setRecord(BaseSequentialStream *chp, int argc, char *argv[]){
822
  if (argc == 1){
823
    chprintf(chp, "Set recording to %d\n", atoi(argv[0]));
824
    global.enableRecord = atoi(argv[0]);
825
  }
826
}
813 827

  
814 828

  
815 829
void zieglerMeth2(BaseSequentialStream *chp, int argc, char *argv[]) {
......
822 836
  int maxDelta = 0;
823 837
  float KCrit = 0.0f;
824 838
  global.sensSamples = 0;
839
  global.maxDist.error = 0;
825 840
  LineFollow lf(&global);
841
  int led = 0;
826 842
 
827 843
  if (argc == 2){
828 844
    chprintf(chp, "KCrti %f\n", atof(argv[0]));
829 845
    chprintf(chp, "Steps %i\n", atoi(argv[1]));
830 846
    KCrit = atof(argv[0]);
831 847
    steps = atoi(argv[1]);
832
  } else{
833
    chprintf(chp, "Usage: dev_ziegler2 <K_crit> <steps>");
848
  } else if (argc == 3){
849
    chprintf(chp, "KCrti %f\n", atof(argv[0]));
850
    chprintf(chp, "Steps %i\n", atoi(argv[1]));
851
    KCrit = atof(argv[0]);
852
    steps = atoi(argv[1]);
853
    global.forwardSpeed = atoi(argv[2]);
854
    
855
  }else{
856
    chprintf(chp, "Usage: dev_ziegler2 <K_crit> <steps> (<speed>)");
834 857
    return;
835 858
  }
859
  global.K_p = KCrit;
860
  for(led=0; led<8; led++){
861
        global.robot.setLightColor(led, Color(Color::BLACK));
862
  }
836 863
  chprintf((BaseSequentialStream*)&global.sercanmux1, "Recodring starts in five seconds...\n");
837 864
  BaseThread::sleep(MS2ST(5000));
838 865
  // global.motorcontrol.setTargetRPM(rpmSpeed[constants::DiWheelDrive::LEFT_WHEEL] * 1000000, rpmSpeed[constants::DiWheelDrive::RIGHT_WHEEL] * 1000000);
839
  
866
  int checkWhite = 0;
867
  int it_switch = steps / 2;
840 868
  for(int s=0; s < steps; s++){
841
    chprintf(chp,"S:%d,",s);
842
    lf.calibrateZiegler(KCrit, rpmSpeed);
869
    // chprintf(chp,"S:%d,",s);
870
    if(global.threshWhite)
871
    if(s < it_switch){
843 872

  
844
    global.motorcontrol.setTargetRPM(rpmSpeed[constants::DiWheelDrive::LEFT_WHEEL] * 1000000, rpmSpeed[constants::DiWheelDrive::RIGHT_WHEEL] * 1000000);
873
      checkWhite = lf.followRightEdge(rpmSpeed);
874
    }else{
875
      checkWhite = lf.followLeftEdge(rpmSpeed);
876
    }
877
    if(checkWhite){
878
      for(led=0; led<8; led++){
879
        global.robot.setLightColor(led, Color(Color::RED));
880
      }
881
      global.motorcontrol.setTargetRPM(0,0);
882
    }else{
883
      global.motorcontrol.setTargetRPM(rpmSpeed[constants::DiWheelDrive::LEFT_WHEEL] * 1000000, rpmSpeed[constants::DiWheelDrive::RIGHT_WHEEL] * 1000000);
884
    }
885
    
886
    
845 887
    BaseThread::sleep(CAN::UPDATE_PERIOD);
846 888
  }
889

  
847 890
  global.motorcontrol.setTargetRPM(0,0);
848 891
}
849 892

  
......
884 927

  
885 928
    global.senseRec[j].FL = FL;
886 929
    global.senseRec[j].FR = FR;
887
    global.senseRec[j].delta = delta;
888 930
    // chprintf(chp,"FL: 0x%x, FR: 0x%x, Delta: %d, ProxyL: %x, ProxyR: %x, MaxDelta: %d\n", 
889 931
    //               vcnl4020Proximity[constants::DiWheelDrive::PROX_FRONT_LEFT],
890 932
    //               vcnl4020Proximity[constants::DiWheelDrive::PROX_FRONT_RIGHT],
......
905 947
void printMove(BaseSequentialStream *chp, int argc, char *argv[]){
906 948

  
907 949
  for (int j=0; j<global.sensSamples;j++){
908
    chprintf(chp,"FL:%d,FR:%d,Delta:%d\n",global.senseRec[j].FL, global.senseRec[j].FR, global.senseRec[j].delta);
950
    chprintf(chp,"FL:%d,FR:%d,Delta:%d,Error:%d\n",global.senseRec[j].FL, global.senseRec[j].FR, global.senseRec[j].delta, global.senseRec[j].error);
909 951
  }
952
  chprintf(chp,"MaxDist: FL:%d,FR:%d,Delta:%d,Error:%d\n",global.maxDist.FL, global.maxDist.FR, global.maxDist.delta, global.maxDist.error);
953

  
910 954

  
911 955
}
912 956

  
......
943 987
  {"calibrate_line", calibrateLineSensores}, 
944 988
  {"record_move_l", recordMove},
945 989
  {"print_record", printMove},
990
  {"setRecord", setRecord},
946 991
  {NULL, NULL}
947 992
};
948 993

  

Also available in: Unified diff