PropWare  3.0.0.229
C++ objects and CMake build system for Parallax Propeller
calibrationResults.c
1 #include "abdrive.h"
2 
3 #ifdef _monitor_
4  volatile char abd_str[128];
5 #endif
6 
7 //#define test_t_interval
8 #ifdef test_t_interval
9  volatile int rec_t[8000 / 4];
10 #endif
11 
12 
13 //volatile int abd_record; // Record values to an array
14 
15 void drive_com(int arrayLcnt, int arrayRcnt,
16  int centerL, int centerR,
17  short *pwAddrL, short *pwAddrR,
18  short *spdAddrL, short *spdAddrR);
19 //void drive_set(int left, int right);
20 void abd_encoders(void *par);
21 //void interpolate(int* ltmp, int* rtmp);
22 void interpolation_table_setup();
23 //void servos_diffDrive(void);
24 //void drive_record(int startStop);
25 //void drive_displayControlSystem(int start, int end);
26 void set_drive_speed(int left, int right);
27 void interpolate2(int *ltmp, int *rtmp);
28 //void drive_rampStep2(int left, int right);
29 void abd_sample(void);
30 
31 
32 // Servo pulse counter
33 volatile unsigned int _servoPulseReps;
34 volatile int abd_dsr; // Distance sampling rate
35 volatile int abd_zeroDelay;
36 volatile int abd_us;
37 volatile int abd_intTabSetup;
38 
39 //static int cog;
40 //static int servoCog2 = 0;
41 //static unsigned int stack[44 + 252];
42 //static unsigned int stack[44 + 352];
43 //static unsigned int servoStack[(160 + (150 * 4)) / 4];
44 
45 //int abd_spdrL[120];
46 //int abd_spdmL[120];
47 //int abd_spdrR[120];
48 //int abd_spdmR[120];
49 short abd_spdrL[120];
50 short abd_spdmL[120];
51 short abd_spdrR[120];
52 short abd_spdmR[120];
53 
54 //static int a = 0;
55 volatile int r;
56 
57 int abd_eeAddr;
58 
59 //static volatile int trimctr;
60 //static volatile int dca, trimticks;
61 
62 static volatile int kp[6];
63 
64 static volatile int ridx;
65 
66 //static volatile int *pwL;
67 //static volatile int *pwR;
68 //static volatile int *spdL;
69 //static volatile int *spdR;
70 
71 static volatile int pcount;
72 static volatile unsigned int _sprOld;
73 
74 //static volatile int phsL;
75 //static volatile int phsR;
76 //static volatile int phs[L];
77 //static volatile int phs[R];
78 static volatile int phs[2];
79 
80 static volatile int phsr[2];
81 
82 //static int trimFunction;
83 //static int encoderFeedback;
84 
85 volatile int abd_blockGoto;
86 
87 // drive_trimset
88 //volatile int abd_trimF[2];
89 //volatile int abd_trimB[2];
90 
91 //volatile int abd_trimticksF;
92 //volatile int abd_trimticksB;
93 
94 volatile int abd_speedOld[2];
95 volatile int abd_stopCtr[2];
96 
97 volatile int abd_stopPulseReps[2];
98 // Measured distance left/right
99 volatile int abd_ticks[2];
100 // Target speed left/right
101 volatile int abd_speedT[2];
102 // Current requested speed
103 volatile int abd_speed[2];
104 
105 
106 volatile int abd_ticksi[2];
107 
108 
109 volatile int abd_ticksf[2];
110 
111 
112 volatile int abd_gotoFlag[2];
113 
114 volatile int abd_rampStep[3];
115 volatile int abd_speedLimit[4];
116 
117 volatile int abd_ticksGuard[2];
118 
119 // distance calculated
120 volatile int abd_dc[2];
121 
122 // distance calculated (accumulated)
123 volatile int abd_dca[2];
124 
125 // error distance
126 volatile int abd_ed[2];
127 
128 // proportional
129 volatile int abd_p[2];
130 
131 // integral
132 volatile int abd_i[2];
133 
134 // Accumulated errors L/R
135 volatile int abd_ea[2];
136 
137 
138 // servoPins
139 volatile int abd_sPin[2];
140 
141 // Encoder Pins
142 volatile int abd_ePin[2];
143 
144 // display
145 volatile int abd_elCnt[2]; // ?????? Instance count different
146 volatile int abd_cntrIdx[2];
147 
148 
149 // Center values
150 static volatile int cntrVal[2];
151 static volatile int ti[2];
152 static volatile int state[2];
153 // servo speeed interpolated
154 static volatile int ssi[2];
155 static volatile int drive[2];
156 
157 static volatile int speedPrev[2];
158 volatile int abd_nudgeCtr[2];
159 volatile int abd_nudgeInc[2]; // ??? remove ???
160 volatile int abd_distError[2];
161 
162 volatile int sign[2];
163 volatile int abd_dist[2];
164 
165 volatile int abd_ditherA[2];
166 volatile int abd_ditherAa[2];
167 volatile int abd_ditherAd[2];
168 volatile int abd_ditherAp[2];
169 
170 volatile int abd_ditherV[2];
171 volatile int abd_ditherVa[2];
172 volatile int abd_ditherVd[2];
173 volatile int abd_ditherVp[2];
174 
175 volatile int abd_speedi[2];
176 volatile int abd_speedd[2];
177 volatile int abd_dvFlag[2];
178 
179 int abd_abs(int value);
180 
181 
182 /*
183 int abd_checkForSwappedCables(void)
184 {
185  int state = 0;
186  if( (abd_elCnt[ABD_L] == 80) && (abd_cntrIdx[ABD_L] == 0))
187  {
188  state |= (1 << 0);
189  }
190  if( (abd_elCnt[ABD_R] == 80) && (abd_cntrIdx[ABD_R] == 0))
191  {
192  state |= (1 << 1);
193  }
194  return state; // Left 1, right 2, both 3
195 }
196 */
197 
198 int abd_checkActivityBotStrings(void)
199 {
200  int state = 0;
201  char str[4];
202  ee_getStr((unsigned char *) str, 3, _ActivityBot_EE_Start_ + 12);
203  if(strncmp(str, "spL", 3) != 0) state |= (1 << 0);
204  /*
205  for(int n = 0; n <= 2; n++)
206  {
207  if(str[n] >= ' ' && str[n] <= 'z')
208  {
209  print("%c", str[n]);
210  }
211  else
212  {
213  print("[%d]", str[n]);
214  }
215  }
216  print("\rcomparison = %d\r", strncmp(str, "spL", 3));
217  */
218 
219  ee_getStr((unsigned char *) str, 3, _ActivityBot_EE_Start_ + 20);
220  if(strncmp(str, "epL", 3) != 0) state |= (1 << 1);
221 
222  return state;
223 
224  /*
225  for(int n = 0; n <= 2; n++)
226  {
227  if(str[n] >= ' ' && str[n] <= 'z')
228  {
229  print("%c", str[n]);
230  }
231  else
232  {
233  print("[%d]", str[n]);
234  }
235  }
236  print("\rcomparison = %d\r", strncmp(str, "epL", 3));
237  */
238  //print("string = %s\r", str);
239 }
240 
241 
242 
243 int abd_checkForSwappedCables(void)
244 {
245  int state = 0;
246  int deviations = 25;
247  int sum = 0;
248  int avgPt = (int)((abd_spdmL[2] + abd_spdmL[3] + abd_spdmL[4]) / 3);
249  if
250  (
251  (avgPt < 60)
252  //&&
253  //(avgPt > 0)
254  )
255  {
256  for(int n = 5; n < 30; n ++)
257  {
258  sum += abd_spdmL[n];
259  if(abd_abs((int)(abd_spdmL[n] - avgPt)) < 8)
260  {
261  deviations--;
262  }
263  //print("deviations = %d\r", deviations);
264  }
265  if((deviations < 4) && (sum != 0)) state |= (1 << 0);
266  }
267 
268  deviations = 17;
269  avgPt = (int)((abd_spdmR[50] + abd_spdmR[51] + abd_spdmR[52]) / 3);
270  sum = 0;
271  if
272  (
273  (avgPt < 50)
274  //&&
275  //(avgPt > 0)
276  )
277  {
278  for(int n = 53; n < 53 + 17; n ++)
279  {
280  sum += abd_spdmR[n];
281  if(abd_abs((int)(abd_spdmR[n] - avgPt)) < 8)
282  {
283  deviations--;
284  }
285  }
286  if((deviations < 4) && (sum != 0)) state |= (1 << 1);
287  }
288  return state; // Left 1, right 2, both 3
289 }
290 
291 
292 int abd_checkForNoSignal(void)
293 {
294  int state = 0;
295  if( (abd_elCnt[ABD_L] == 67) && (abd_cntrIdx[ABD_L] == 1))
296  {
297  state |= (1 << 0);
298  }
299  if( (abd_elCnt[ABD_R] == 199) && (abd_cntrIdx[ABD_R] == 49))
300  {
301  state |= (1 << 1);
302  }
303  return state; // Left 1, right 2, both 3
304 }
305 
306 
307 int abd_checkCenterPulseWidth(void)
308 {
309  int state = 0;
310  if( (abd_abs(abd_spdrL[abd_cntrIdx[ABD_L]]) > 45) )
311  {
312  state |= (1 << 0);
313  }
314  if( (abd_abs(abd_spdrR[abd_cntrIdx[ABD_R]]) > 45) )
315  {
316  state |= (1 << 1);
317  }
318  return state;
319 }
320 
321 
322 int abd_checkServoCalSupply(int side)
323 {
324  int sum = 1;
325  for(int n = 1; n <= 10; n++)
326  {
327  if(side == ABD_L)
328  {
329  sum += abd_spdmL[n];
330  sum += (abd_spdmL[abd_elCnt[side] - 1 - n]);
331  }
332  else
333  {
334  sum += abd_spdmR[n];
335  sum += (abd_spdmR[abd_elCnt[side] - 1 - n]);
336  }
337  }
338  return sum/20;
339 }
340 
341 
342 void abd_displaySide(int side, char *s)
343 {
344  switch(side - 1)
345  {
346  case ABD_L:
347  {
348  sprint(s, "the ActivityBot's left ");
349  break;
350  }
351  case ABD_R:
352  {
353  sprint(s, "the ActivityBot's right ");
354  break;
355  }
356  case ABD_B:
357  {
358  sprint(s, "either of the ActivityBot's ");
359  break;
360  }
361  case (ABD_B + 1):
362  {
363  sprint(s, "both of the ActivityBot's ");
364  break;
365  }
366  }
367 }
368 
369 
371 {
372  char s[20];
373  if(!abd_intTabSetup) interpolation_table_setup();
374  int cfgStrs = abd_checkActivityBotStrings();
375  int cables = abd_checkForSwappedCables();
376  int noSignal = abd_checkForNoSignal();
377  int centerError = abd_checkCenterPulseWidth();
378  int supplyL = abd_checkServoCalSupply(ABD_L);
379  int supplyR = abd_checkServoCalSupply(ABD_R);
380 
381  /*
382  print("%d swapped cable errors\r", cables);
383  print("%d missing encoder signals\r", noSignal);
384  print("%d servos need centering\r", centerError);
385  print("%d average max speed on left\r", supplyL);
386  print("%d average max speed on right\r\r", supplyR);
387  */
388 
389  if
390  (
391  (cfgStrs == 0)
392  &&
393  (cables == 0)
394  &&
395  (noSignal == 0)
396  &&
397  (centerError == 0)
398  &&
399  (supplyL >= 150)
400  &&
401  (supplyR >= 150)
402  &&
403  (supplyL < 205)
404  &&
405  (supplyR < 205)
406  )
407  {
408  print("The calibration completed successfully!\r\r");
409  print("Have fun with your ActivityBot. Make sure\r\r");
410  print("to try the activities at learn.parallax.com.\r\r");
411  }
412  else
413  {
414  print("One or more problems were detected. For\r");
415  print("help, go to the troubleshooting page in\r");
416  print("the learn.parallax.com tutorial you are\r");
417  print("following.\r\r");
418  print("Details:\r\r");
419 
420  pause(10);
421  //
422  if(cfgStrs)
423  {
424  print("It does not look like the calibration\r");
425  print("procedure has been completed.\r\r");
426  }
427  //
428  if(
429  //(noSignal != 3)
430  //&&
431  cables
432  )
433  {
434  print("Either your ActivityBot's servo cables\r");
435  print("or its encoder cables are swapped.\r\r");
436  }
437 
438  if(noSignal && (cables == 0))
439  {
440  print("The Propeller cannot detect\r");
441  abd_displaySide(noSignal, s);
442  print("%s", s);
443  print("encoder signal(s).\r\r");
444  }
445 
446  if
447  (
448  centerError
449  &&
450  !
451  (
452  cables
453  ||
454  noSignal
455  )
456  )
457  {
458  if(centerError == 3) centerError = 4;
459  print("The servo on \r");
460  abd_displaySide(centerError, s);
461  print("%s", s);
462  print("side(s) needs mechanical\r");
463  print("calibration.\r\r");
464  }
465 
466  if
467  (
468  !
469  (
470  cables
471  ||
472  noSignal
473  ||
474  centerError
475  )
476  )
477  {
478  int supply = (supplyL + supplyR) / 2;
479  if(supply < 100)
480  {
481  print("The ActivityBot's batteries are either\r");
482  print("really dead, or one of the cells is in\r");
483  print("the battery holder backwards. A short \r");
484  print("circuit in the prototyping area could also \r");
485  print("explain the slow-moving behavior.\r\r");
486  }
487  else if(supply < 140)
488  {
489  print("The ActivityBot's batties are either dead,\r");
490  print("or the P13/P12 PWR select jumper is still at\r");
491  print("the 5V setting. It should be at the VIN\r");
492  print("setting.\r\r");
493  }
494  else if(supply < 150)
495  {
496  print("The ActivityBot's batteries are too low.\r");
497  print("Try a new set of 5 alkaline batteries, or\r");
498  print("recharge your power pack to the 7 to 8 V range.\r\r");
499  }
500  else if(supply > 205)
501  {
502  print("Yikes! Servo speeds indicate your\r");
503  print("ActivityBot may have a power pack that's\r");
504  print("more than 8.5 V. Use an appropriate\r");
505  print("power source to avoid servo damage.\r\r");
506  }
507  }
508  }
509 }
510 
511 
512 /*
513 void drive_calibrationResults(void)
514 {
515  if(!abd_intTabSetup) interpolation_table_setup();
516  int cables = abd_checkForSwappedCables();
517  int noSignal = abd_checkForNoSignal();
518  int centerError = abd_checkCenterPulseWidth();
519  int supplyL = abd_checkServoCalSupply(ABD_L);
520  int supplyR = abd_checkServoCalSupply(ABD_R);
521 
522  print("%d swapped cable errors\r", cables);
523  print("%d missing encoder signals\r", noSignal);
524  print("%d servos need centering\r", centerError);
525  print("%d average max speed on left\r", supplyL);
526  print("%d average max speed on right\r\r", supplyR);
527 
528  if(cables == 1)
529  {
530  print("Cables are swapped!\r\r");
531  }
532 }
533 */
pause
void pause(int time)
Delay cog from moving on to the next statement for a certain length of time.
Definition: libws2812.c:125
_ActivityBot_EE_Start_
#define _ActivityBot_EE_Start_
ActivityBot EEPROM calibration data start address.
Definition: abcalibrate.h:58
print
int print(const char *format,...) __attribute__((format(printf
Print format "..." args to the default simple terminal device. The output is limited to 256 bytes.
drive_calibrationResults
void drive_calibrationResults(void)
Uses the calibration settings to find common circuit mistakes that prevent the ActivityBot from opera...
Definition: calibrationResults.c:370
sprint
int int int sprint(char *buffer, const char *format,...) __attribute__((format(printf
Print format "..." args to the output buffer. The output buffer must be big enough for the output.
ee_getStr
unsigned char * ee_getStr(unsigned char *s, int n, int addr)
Fetch a string of byte values starting at a certain address in Propeller Chip's dedicated EEPROM.
abdrive.h
This library takes care of encoder monitoring and servo signaling, and provides a simple set of funct...