source: Sophya/trunk/Poubelle/archTOI.old/gyrocalibrator.cc@ 678

Last change on this file since 678 was 635, checked in by ansari, 26 years ago

warnings linux egcs, et struct Horloge

File size: 6.6 KB
Line 
1// gyrocalibrator.cc
2// Eric Aubourg CEA/DAPNIA/SPP octobre 1999
3
4// assumption : same calibration for all gyros...
5
6// Warning, current implementation can only output ONE calibration.
7// workaround : clone the object for different options.
8
9
10#include "gyrocalibrator.h"
11#include "archexc.h"
12#include "archparam.h"
13
14#define gyroCal "gyroCal"
15#define gyroOffset "gyroOffset"
16#define gyroSpeed "gyroSpeed"
17
18GyroCalibrator::GyroCalibrator() {
19 possibleTOIs.insert(TOI(gyroCal, TOI::all, "linearCal", "deg/s/V"));
20 possibleTOIs.insert(TOI(gyroOffset, TOI::all, "linearCal", "deg/s/V"));
21 possibleTOIs.insert(TOI(gyroSpeed, TOI::all , "linearCal", "deg/s"));
22
23 needAfter = 3600; // about one turn...
24 startSample = -1;
25 lastRotSpeed = -1;
26 lastFence1 = lastFence2 = -1;
27 for (int i=0; i<3; i++) {
28 lastCalib[i] = -99999;
29 lastOffset[i] = 0;
30 }
31 gyroProducer = NULL;
32}
33
34string GyroCalibrator::getName() {
35 return("GyroCalibrator 1.0");
36}
37
38
39set<TOI> GyroCalibrator::reqTOIFor(TOI const&) {
40 set<TOI> t;
41 t.insert(TOI("rotSpeed", TOI::unspec)); // pull only
42 t.insert(TOI("rotSpeedSample1", TOI::unspec)); // pull only
43 t.insert(TOI("rotSpeedSample2", TOI::unspec)); // pull only
44 t.insert(TOI("gyroV", 0)); // push
45 t.insert(TOI("gyroV", 1)); // push
46 t.insert(TOI("gyroV", 2)); // push
47 return t;
48}
49
50void GyroCalibrator::dataFeed(TOIProducer* , TOI const& toi, long sampleNum, double value) {
51 // if (toi.name != "gyroV" || toi.index != 2) return;
52 if (toi.name != "gyroV" ) return;
53
54 if (gyro[2].empty()) {
55 startSample = sampleNum;
56 }
57
58 gyro[toi.index].push_back(value);
59}
60
61void GyroCalibrator::recomputeCalib() {
62 // Integral of gyro signal between the two fences.
63
64 // can we do it ?
65 for (int i=0; i<3; i++) {
66 lastCalib[i] = -99999;
67 }
68 if (startSample > lastFence1) return;
69 if ((long)gyro[2].size()+startSample < lastFence2) return;
70
71 double sum[3];
72 for (int i=0; i<3; i++) {
73 sum[i] = 0;
74 }
75 vector<double>::iterator i0 = gyro[0].begin() + (lastFence1-startSample);
76 vector<double>::iterator i1 = gyro[1].begin() + (lastFence1-startSample);
77 vector<double>::iterator i2 = gyro[2].begin() + (lastFence1-startSample);
78 vector<double>::iterator stop2 = gyro[2].begin() + (lastFence2-startSample);
79 for (; i2 != stop2; i0++,i1++,i2++) {
80 sum[0] += *i0;
81 sum[1] += *i1;
82 sum[2] += *i2;
83 }
84
85 // average of signal
86 sum[0] /= (lastFence2-lastFence1);
87 sum[1] /= (lastFence2-lastFence1);
88 sum[2] /= (lastFence2-lastFence1);
89
90 lastOffset[0] = sum[0];
91 lastOffset[1] = sum[1];
92 lastOffset[2] = (lastOffset[0] + lastOffset[1])/2.; // We don't have a better estimate...
93
94 lastCalib[2] = lastRotSpeed / (sum[2] - lastOffset[2]);
95 lastCalib[0] = lastCalib[1] = lastCalib[2]; // We don't have a better estimate...
96}
97
98bool GyroCalibrator::fetchFences(long sampleNum) {
99 map<TOI, TOIProducer*> & m = (*(neededTOIs.begin())).second;
100
101 long oldf2 = lastFence2;
102 for (map<TOI, TOIProducer*>::iterator i = m.begin(); i != m.end(); i++) {
103 TOI const& inToi = (*i).first;
104 TOIProducer* prod = (*i).second;
105 if (inToi.name == "rotSpeed") lastRotSpeed = prod->getValue(sampleNum, inToi);
106 if (inToi.name == "rotSpeedSample1") lastFence1 = long(prod->getValue(sampleNum, inToi));
107 if (inToi.name == "rotSpeedSample2") lastFence2 = long(prod->getValue(sampleNum, inToi));
108 if (inToi.name == "gyroV") gyroProducer = prod;
109 }
110
111 return (oldf2 != lastFence2);
112}
113
114
115bool GyroCalibrator::canGetValue(long sampleNum, TOI const& ) {
116 // We can get value if sampleNum is between the two fences, or
117 // if a new fence later than sampleNum is now available.
118 // In any case, we must have gyro data up to the highest fence.
119
120 if (startSample > lastFence1) return false; // will never work...
121 if (sampleNum >= lastFence1 && sampleNum < lastFence2 && (gyro[2].size()+startSample >= lastFence2)) return true;
122 if ((long)gyro[2].size()+startSample < lastFence2) return false; // We have to wait for more gyro data
123 if (fetchFences(sampleNum)) {
124 recomputeCalib(); // do it now to keep a consistent state
125 }
126 if (sampleNum >= lastFence1 && sampleNum < lastFence2) {
127 return true;
128 } else {
129 return false;
130 }
131}
132
133bool GyroCalibrator::canGetValueLater(long sampleNum, TOI const& ) {
134 if (sampleNum >= lastFence1 && sampleNum < lastFence2 && ((long)gyro[2].size()+startSample >= lastFence2)) return false;
135 // because can get now
136 if (sampleNum >= lastFence2) { // check if new fence...
137 if (fetchFences(sampleNum)) {
138 recomputeCalib(); // do it now to keep a consistent state
139 }
140 }
141
142 // Si nos fournisseurs ne peuvent pas, nous non plus...
143 map<TOI, TOIProducer*> & m = (*(neededTOIs.begin())).second;
144 for (map<TOI, TOIProducer*>::iterator i = m.begin(); i != m.end(); i++) {
145 TOI const& inToi = (*i).first;
146 TOIProducer* prod = (*i).second;
147 if (!prod->canGetValue(sampleNum, inToi) && !prod->canGetValueLater(sampleNum, inToi)) return false;
148
149 }
150
151 if (lastFence1<0 || lastFence2<0) return true;
152 if (sampleNum > lastFence2) return true;
153 return (startSample <= lastFence1 && (long)gyro[2].size()+startSample < lastFence2 && sampleNum > lastFence1);
154}
155
156double GyroCalibrator::getValue(long sampleNum, TOI const& toi) {
157 if (startSample > lastFence1) return -1; // will never work...
158 if ((long)gyro[2].size()+startSample < lastFence2) return -1; // We have to wait for more gyro data
159 if (!(sampleNum >= lastFence1 && sampleNum < lastFence2)) {
160 if (fetchFences(sampleNum)) {
161 if ((long)gyro[2].size()+startSample < lastFence2) return -1; // We have to wait for more gyro data
162 recomputeCalib(); // do it now to keep a consistent state
163 }
164 }
165
166 if (!(sampleNum >= lastFence1 && sampleNum < lastFence2))
167 return -1;
168
169 if (lastCalib[0] < 0) recomputeCalib();
170
171 if (toi.name == gyroCal) return lastCalib[toi.index];
172 if (toi.name == gyroOffset) return lastOffset[toi.index];
173 if (toi.name == gyroSpeed) {
174 TOI toi2 = TOI("gyroV", toi.index); // $CHECK$ maybe should get from reqtoi ?
175 double gv = gyroProducer->getValue(sampleNum, toi2);
176 return (gv-lastOffset[toi.index])*lastCalib[toi.index];
177 }
178 throw ArchExc("Cannot produce "+toi.fullName());
179}
180
181
182void GyroCalibrator::propagateLowBound(TOI const& toi, long sampleNum) {
183 if (startSample < lastFence1) {
184 if (gyro[0].size() > lastFence1 - startSample) {
185 for (int i=0; i<3; i++) {
186 vector<double>::iterator x = gyro[i].begin() + lastFence1 - startSample;
187 gyro[i].erase(gyro[i].begin(), x);
188 }
189 startSample = lastFence1;
190 }
191 }
192 TOIPullProducer::propagateLowBound(toi, sampleNum);
193}
194
Note: See TracBrowser for help on using the repository browser.