Revision b4885314
boards/DiWheelDrive/board.c | ||
---|---|---|
96 | 96 |
palSetPad(GPIOC, GPIOC_SYS_PD_N); |
97 | 97 |
} |
98 | 98 |
|
99 |
inline void boardClearI2CBus(const uint8_t scl_pad) { |
|
99 |
inline void boardClearI2CBus(const uint8_t scl_pad, const uint8_t sda_pad) {
|
|
100 | 100 |
|
101 | 101 |
uint8_t i; |
102 | 102 |
|
103 |
// configure I²C SCL open drain |
|
103 |
// configure I²C SCL and SDA open drain
|
|
104 | 104 |
palSetPadMode(GPIOB, scl_pad, PAL_MODE_OUTPUT_OPENDRAIN); |
105 |
palSetPadMode(GPIOB, sda_pad, PAL_MODE_OUTPUT_OPENDRAIN); |
|
105 | 106 |
|
106 |
// perform bus clear as per I²C Specification v5 3.1.16 |
|
107 |
for (i = 0x00u; i < 0x09u; i++) { |
|
107 |
// perform a 2-wire software reset for the eeprom (see AT24C01BN-SH-B datasheet, chapter 3) |
|
108 |
// note: clock is ~50kHz (20us per cycle) |
|
109 |
palSetPad(GPIOB, sda_pad); |
|
110 |
palClearPad(GPIOB, scl_pad); |
|
111 |
chThdSleepMicroseconds(10); |
|
112 |
palSetPad(GPIOB, scl_pad); |
|
113 |
chThdSleepMicroseconds(5); |
|
114 |
palClearPad(GPIOB, sda_pad); |
|
115 |
chThdSleepMicroseconds(5); |
|
116 |
palClearPad(GPIOB, scl_pad); |
|
117 |
chThdSleepMicroseconds(5); |
|
118 |
palSetPad(GPIOB, sda_pad); |
|
119 |
chThdSleepMicroseconds(5); |
|
120 |
for (i = 0; i < 9; ++i) { |
|
121 |
palSetPad(GPIOB, scl_pad); |
|
122 |
chThdSleepMicroseconds(10); |
|
123 |
palClearPad(GPIOB, scl_pad); |
|
124 |
chThdSleepMicroseconds(10); |
|
125 |
} |
|
126 |
palSetPad(GPIOB, scl_pad); |
|
127 |
chThdSleepMicroseconds(5); |
|
128 |
palClearPad(GPIOB, sda_pad); |
|
129 |
chThdSleepMicroseconds(5); |
|
130 |
palClearPad(GPIOB, scl_pad); |
|
131 |
chThdSleepMicroseconds(10); |
|
132 |
palSetPad(GPIOB, scl_pad); |
|
133 |
chThdSleepMicroseconds(5); |
|
134 |
palSetPad(GPIOB, sda_pad); |
|
135 |
chThdSleepMicroseconds(5); |
|
136 |
palClearPad(GPIOB, scl_pad); |
|
137 |
chThdSleepMicroseconds(10); |
|
138 |
|
|
139 |
// perform bus clear as per I²C Specification v6 3.1.16 |
|
140 |
// note: clock is 100kHz (10us per cycle) |
|
141 |
for (i = 0; i < 10; i++) { |
|
108 | 142 |
palClearPad(GPIOB, scl_pad); |
109 | 143 |
chThdSleepMicroseconds(5); |
110 | 144 |
palSetPad(GPIOB, scl_pad); |
... | ... | |
113 | 147 |
|
114 | 148 |
// reconfigure I²C SCL |
115 | 149 |
palSetPadMode(GPIOB, scl_pad, PAL_MODE_STM32_ALTERNATE_OPENDRAIN); |
150 |
palSetPadMode(GPIOB, sda_pad, PAL_MODE_STM32_ALTERNATE_OPENDRAIN); |
|
116 | 151 |
|
152 |
return; |
|
117 | 153 |
} |
boards/DiWheelDrive/board.h | ||
---|---|---|
198 | 198 |
void boardRequestShutdown(void); |
199 | 199 |
void boardStandby(void); |
200 | 200 |
void boardWakeup(void); |
201 |
void boardClearI2CBus(const uint8_t scl_pad); |
|
201 |
void boardClearI2CBus(const uint8_t scl_pad, const uint8_t sda_pad);
|
|
202 | 202 |
#ifdef __cplusplus |
203 | 203 |
} |
204 | 204 |
#endif |
boards/LightRing/board.c | ||
---|---|---|
64 | 64 |
|
65 | 65 |
} |
66 | 66 |
|
67 |
inline void boardClearI2CBus(const uint8_t scl_pad) { |
|
67 |
inline void boardClearI2CBus(const uint8_t scl_pad, const uint8_t sda_pad) {
|
|
68 | 68 |
|
69 | 69 |
uint8_t i; |
70 | 70 |
|
71 |
// configure I²C SCL open drain |
|
71 |
// configure I²C SCL and SDA open drain
|
|
72 | 72 |
palSetPadMode(GPIOB, scl_pad, PAL_MODE_OUTPUT_OPENDRAIN); |
73 |
palSetPadMode(GPIOB, sda_pad, PAL_MODE_OUTPUT_OPENDRAIN); |
|
73 | 74 |
|
74 |
// perform bus clear as per I²C Specification v5 3.1.16 |
|
75 |
for (i = 0x00u; i < 0x09u; i++) { |
|
75 |
// perform a 2-wire software reset for the eeprom (see AT24C01BN-SH-B datasheet, chapter 3) |
|
76 |
// note: clock is ~50kHz (20us per cycle) |
|
77 |
palSetPad(GPIOB, sda_pad); |
|
78 |
palClearPad(GPIOB, scl_pad); |
|
79 |
chThdSleepMicroseconds(10); |
|
80 |
palSetPad(GPIOB, scl_pad); |
|
81 |
chThdSleepMicroseconds(5); |
|
82 |
palClearPad(GPIOB, sda_pad); |
|
83 |
chThdSleepMicroseconds(5); |
|
84 |
palClearPad(GPIOB, scl_pad); |
|
85 |
chThdSleepMicroseconds(5); |
|
86 |
palSetPad(GPIOB, sda_pad); |
|
87 |
chThdSleepMicroseconds(5); |
|
88 |
for (i = 0; i < 9; ++i) { |
|
89 |
palSetPad(GPIOB, scl_pad); |
|
90 |
chThdSleepMicroseconds(10); |
|
91 |
palClearPad(GPIOB, scl_pad); |
|
92 |
chThdSleepMicroseconds(10); |
|
93 |
} |
|
94 |
palSetPad(GPIOB, scl_pad); |
|
95 |
chThdSleepMicroseconds(5); |
|
96 |
palClearPad(GPIOB, sda_pad); |
|
97 |
chThdSleepMicroseconds(5); |
|
98 |
palClearPad(GPIOB, scl_pad); |
|
99 |
chThdSleepMicroseconds(10); |
|
100 |
palSetPad(GPIOB, scl_pad); |
|
101 |
chThdSleepMicroseconds(5); |
|
102 |
palSetPad(GPIOB, sda_pad); |
|
103 |
chThdSleepMicroseconds(5); |
|
104 |
palClearPad(GPIOB, scl_pad); |
|
105 |
chThdSleepMicroseconds(10); |
|
106 |
|
|
107 |
// perform bus clear as per I²C Specification v6 3.1.16 |
|
108 |
// note: clock is 100kHz (10us per cycle) |
|
109 |
for (i = 0; i < 10; i++) { |
|
76 | 110 |
palClearPad(GPIOB, scl_pad); |
77 | 111 |
chThdSleepMicroseconds(5); |
78 | 112 |
palSetPad(GPIOB, scl_pad); |
... | ... | |
81 | 115 |
|
82 | 116 |
// reconfigure I²C SCL |
83 | 117 |
palSetPadMode(GPIOB, scl_pad, PAL_MODE_STM32_ALTERNATE_OPENDRAIN); |
118 |
palSetPadMode(GPIOB, sda_pad, PAL_MODE_STM32_ALTERNATE_OPENDRAIN); |
|
84 | 119 |
|
120 |
return; |
|
85 | 121 |
} |
boards/LightRing/board.h | ||
---|---|---|
178 | 178 |
void boardInit(void); |
179 | 179 |
void boardRequestShutdown(void); |
180 | 180 |
void boardStandby(void); |
181 |
void boardClearI2CBus(const uint8_t scl_pad); |
|
181 |
void boardClearI2CBus(const uint8_t scl_pad, const uint8_t sda_pad);
|
|
182 | 182 |
#ifdef __cplusplus |
183 | 183 |
} |
184 | 184 |
#endif |
boards/PowerManagement/board.c | ||
---|---|---|
146 | 146 |
palSetPad(GPIOC, GPIOC_SYS_PD_N); |
147 | 147 |
} |
148 | 148 |
|
149 |
inline void boardClearI2CBus(const uint8_t scl_pad) { |
|
149 |
inline void boardClearI2CBus(const uint8_t scl_pad, const uint8_t sda_pad) {
|
|
150 | 150 |
|
151 | 151 |
uint8_t i; |
152 | 152 |
|
153 |
// configure I²C SCL open drain |
|
153 |
// configure I²C SCL and SDA open drain
|
|
154 | 154 |
palSetPadMode(GPIOB, scl_pad, PAL_MODE_OUTPUT_OPENDRAIN); |
155 |
palSetPadMode(GPIOB, sda_pad, PAL_MODE_OUTPUT_OPENDRAIN); |
|
155 | 156 |
|
156 |
// perform bus clear as per I²C Specification v5 3.1.16 |
|
157 |
for (i = 0x00u; i < 0x09u; i++) { |
|
157 |
// perform a 2-wire software reset for the eeprom (see AT24C01BN-SH-B datasheet, chapter 3) |
|
158 |
// note: clock is ~50kHz (20us per cycle) |
|
159 |
palSetPad(GPIOB, sda_pad); |
|
160 |
palClearPad(GPIOB, scl_pad); |
|
161 |
chThdSleepMicroseconds(10); |
|
162 |
palSetPad(GPIOB, scl_pad); |
|
163 |
chThdSleepMicroseconds(5); |
|
164 |
palClearPad(GPIOB, sda_pad); |
|
165 |
chThdSleepMicroseconds(5); |
|
166 |
palClearPad(GPIOB, scl_pad); |
|
167 |
chThdSleepMicroseconds(5); |
|
168 |
palSetPad(GPIOB, sda_pad); |
|
169 |
chThdSleepMicroseconds(5); |
|
170 |
for (i = 0; i < 9; ++i) { |
|
171 |
palSetPad(GPIOB, scl_pad); |
|
172 |
chThdSleepMicroseconds(10); |
|
173 |
palClearPad(GPIOB, scl_pad); |
|
174 |
chThdSleepMicroseconds(10); |
|
175 |
} |
|
176 |
palSetPad(GPIOB, scl_pad); |
|
177 |
chThdSleepMicroseconds(5); |
|
178 |
palClearPad(GPIOB, sda_pad); |
|
179 |
chThdSleepMicroseconds(5); |
|
180 |
palClearPad(GPIOB, scl_pad); |
|
181 |
chThdSleepMicroseconds(10); |
|
182 |
palSetPad(GPIOB, scl_pad); |
|
183 |
chThdSleepMicroseconds(5); |
|
184 |
palSetPad(GPIOB, sda_pad); |
|
185 |
chThdSleepMicroseconds(5); |
|
186 |
palClearPad(GPIOB, scl_pad); |
|
187 |
chThdSleepMicroseconds(10); |
|
188 |
|
|
189 |
// perform bus clear as per I²C Specification v6 3.1.16 |
|
190 |
// note: clock is 100kHz (10us per cycle) |
|
191 |
for (i = 0; i < 10; i++) { |
|
158 | 192 |
palClearPad(GPIOB, scl_pad); |
159 | 193 |
chThdSleepMicroseconds(5); |
160 | 194 |
palSetPad(GPIOB, scl_pad); |
... | ... | |
163 | 197 |
|
164 | 198 |
// reconfigure I²C SCL |
165 | 199 |
palSetPadMode(GPIOB, scl_pad, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); |
200 |
palSetPadMode(GPIOB, sda_pad, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); |
|
201 |
|
|
202 |
return; |
|
203 |
} |
|
204 |
|
|
205 |
inline void boardResetBQ27500I2C(const uint8_t scl_pad, const uint8_t sda_pad) { |
|
206 |
|
|
207 |
// configure I²C SCL and SDA open drain |
|
208 |
palSetPadMode(GPIOB, scl_pad, PAL_MODE_OUTPUT_OPENDRAIN); |
|
209 |
palSetPadMode(GPIOB, sda_pad, PAL_MODE_OUTPUT_OPENDRAIN); |
|
210 |
|
|
211 |
// BQ27500: reset by holding bus low for t_BUSERR (17.3 - 21.2 seconds) |
|
212 |
palClearPad(GPIOB, scl_pad); |
|
213 |
palClearPad(GPIOB, sda_pad); |
|
214 |
chThdSleepSeconds(20); |
|
215 |
|
|
216 |
boardClearI2CBus(scl_pad, sda_pad); |
|
166 | 217 |
|
218 |
return; |
|
167 | 219 |
} |
boards/PowerManagement/board.h | ||
---|---|---|
375 | 375 |
void boardStandby(void); |
376 | 376 |
void boardStop(const uint8_t lpds, const uint8_t fpds); |
377 | 377 |
void boardWakeup(void); |
378 |
void boardClearI2CBus(const uint8_t scl_pad); |
|
378 |
void boardClearI2CBus(const uint8_t scl_pad, const uint8_t sda_pad); |
|
379 |
void boardResetBQ27500I2C(const uint8_t scl_pad, const uint8_t sda_pad); |
|
379 | 380 |
#ifdef __cplusplus |
380 | 381 |
} |
381 | 382 |
#endif |
components/ControllerAreaNetworkRx.cpp | ||
---|---|---|
99 | 99 |
} |
100 | 100 |
break; |
101 | 101 |
|
102 |
case CAN::MAGNETOMETER_X_ID: |
|
103 |
if (frame->DLC == 4) { |
|
104 |
magnetometerValue[0] = frame->data32[0]; |
|
105 |
return RDY_OK; |
|
106 |
} |
|
107 |
break; |
|
108 |
|
|
109 |
case CAN::MAGNETOMETER_Y_ID: |
|
110 |
if (frame->DLC == 4) { |
|
111 |
magnetometerValue[1] = frame->data32[0]; |
|
112 |
return RDY_OK; |
|
113 |
} |
|
114 |
break; |
|
115 |
|
|
116 |
case CAN::MAGNETOMETER_Z_ID: |
|
117 |
if (frame->DLC == 4) { |
|
118 |
magnetometerValue[2] = frame->data32[0]; |
|
119 |
return RDY_OK; |
|
120 |
} |
|
121 |
break; |
|
122 |
|
|
123 |
case CAN::GYROSCOPE_ID: |
|
124 |
if (frame->DLC == 6) { |
|
125 |
gyroscopeValue[0] = frame->data16[0]; |
|
126 |
gyroscopeValue[1] = frame->data16[1]; |
|
127 |
gyroscopeValue[2] = frame->data16[2]; |
|
128 |
return RDY_OK; |
|
129 |
} |
|
130 |
break; |
|
131 |
|
|
102 | 132 |
default: |
103 | 133 |
break; |
104 | 134 |
} |
... | ... | |
127 | 157 |
return this->robotId; |
128 | 158 |
} |
129 | 159 |
|
160 |
int32_t ControllerAreaNetworkRx::getMagnetometerValue(int axis) |
|
161 |
{ |
|
162 |
return this->magnetometerValue[axis]; |
|
163 |
} |
|
164 |
|
|
165 |
int16_t ControllerAreaNetworkRx::getGyroscopeValue(int axis) |
|
166 |
{ |
|
167 |
return this->gyroscopeValue[axis]; |
|
168 |
} |
|
169 |
|
|
130 | 170 |
|
131 | 171 |
uint16_t ControllerAreaNetworkRx::getProximityFloorValue(int index) { |
132 | 172 |
return this->proximityFloorValue[index]; |
components/Odometry.cpp | ||
---|---|---|
15 | 15 |
using namespace constants::DiWheelDrive; |
16 | 16 |
|
17 | 17 |
|
18 |
Odometry::Odometry(MotorIncrements* mi) |
|
18 |
Odometry::Odometry(MotorIncrements* mi, L3G4200D* gyroscope)
|
|
19 | 19 |
: BaseStaticThread<512>(), |
20 | 20 |
motorIncrements(mi), |
21 |
gyro(gyroscope), |
|
21 | 22 |
eventSource(), |
22 | 23 |
period(50), |
23 | 24 |
incrementsPerRevolution(incrementsPerRevolution), |
... | ... | |
101 | 102 |
while (!this->shouldTerminate()) { |
102 | 103 |
time += MS2ST(this->period); |
103 | 104 |
|
104 |
// Update the base distance, because it may change after an calibration
|
|
105 |
// Update the base distance, because it may change after a calibration |
|
105 | 106 |
this->updateWheelBaseDistance(); |
106 | 107 |
|
107 | 108 |
// Get the actual speed |
... | ... | |
109 | 110 |
|
110 | 111 |
// Calculate the odometry |
111 | 112 |
this->updateOdometry(); |
113 |
|
|
112 | 114 |
|
113 | 115 |
// chprintf((BaseSequentialStream*) &SD1, "X:%f Y:%f Phi:%f", this->pX,this->pY, this->pPhi); |
114 | 116 |
// chprintf((BaseSequentialStream*) &SD1, "\r\n"); |
115 | 117 |
// chprintf((BaseSequentialStream*) &SD1, "distance_left:%f distance_right:%f", this->distance[0],this->distance[1]); |
116 | 118 |
// chprintf((BaseSequentialStream*) &SD1, "\r\n"); |
117 | 119 |
|
118 |
chThdSleepUntil(time); |
|
120 |
if (time >= System::getTime()) { |
|
121 |
chThdSleepUntil(time); |
|
122 |
} else { |
|
123 |
chprintf((BaseSequentialStream*) &SD1, "WARNING Odometry: Unable to keep track\r\n"); |
|
124 |
} |
|
119 | 125 |
} |
120 | 126 |
|
121 | 127 |
return true; |
... | ... | |
125 | 131 |
|
126 | 132 |
// Get the temporary position and error |
127 | 133 |
float Cp3x3[9]; |
134 |
uint32_t angular_ud; |
|
128 | 135 |
chSysLock(); |
129 | 136 |
float pX = this->pX; |
130 | 137 |
float pY = this->pY; |
131 | 138 |
float pPhi = this->pPhi; |
132 | 139 |
Matrix::copy<float>(this->Cp3x3,3,3,Cp3x3,3,3); |
140 |
// Get the differentail gyro information and reset it |
|
141 |
angular_ud = gyro->getAngular_ud(L3G4200D::AXIS_Z); |
|
142 |
gyro->angularReset(); |
|
133 | 143 |
chSysUnlock(); |
134 | 144 |
|
135 | 145 |
//////////////// |
... | ... | |
137 | 147 |
//////////////// |
138 | 148 |
|
139 | 149 |
// TMP: Rotated angular |
140 |
float dPhi = (this->distance[RIGHT_WHEEL] - this->distance[LEFT_WHEEL]) / this->wheelBaseDistanceSI; |
|
150 |
// float dPhi = (this->distance[RIGHT_WHEEL] - this->distance[LEFT_WHEEL]) / this->wheelBaseDistanceSI; |
|
151 |
float dPhi = ((float(angular_ud * 1e-3) * M_PI ) * 1e-3) / 180.0f; |
|
141 | 152 |
|
142 | 153 |
// TMP: Moved distance |
143 | 154 |
float dDistance = (this->distance[RIGHT_WHEEL] + this->distance[LEFT_WHEEL]) / 2.0f; |
components/accel/lis331dlh.cpp | ||
---|---|---|
5 | 5 |
#include <amiro/accel/lis331dlh.hpp> |
6 | 6 |
#include <chprintf.h> |
7 | 7 |
#include <cmath> // abs() |
8 |
#include <amiro/Constants.h> |
|
8 | 9 |
|
9 | 10 |
namespace amiro { |
10 | 11 |
|
... | ... | |
72 | 73 |
|
73 | 74 |
this->eventSource.broadcastFlags(0); |
74 | 75 |
|
75 |
this->waitAnyEventTimeout(ALL_EVENTS, MS2ST(200));
|
|
76 |
this->waitAnyEventTimeout(ALL_EVENTS, CAN::UPDATE_PERIOD_MSEC);
|
|
76 | 77 |
|
77 | 78 |
} |
78 | 79 |
return RDY_OK; |
components/gyro/l3g4200d.cpp | ||
---|---|---|
1 |
#include <ch.hpp> |
|
2 |
#include <hal.h> |
|
3 |
#include <chprintf.h> |
|
1 | 4 |
#include <string.h> |
2 | 5 |
|
3 | 6 |
#include <amiro/util/util.h> |
4 | 7 |
#include <amiro/bus/spi/HWSPIDriver.hpp> |
5 | 8 |
#include <amiro/gyro/l3g4200d.hpp> |
9 |
#include <amiro/Constants.h> |
|
10 |
|
|
11 |
using namespace chibios_rt; |
|
6 | 12 |
|
7 | 13 |
namespace amiro { |
8 | 14 |
|
9 | 15 |
L3G4200D::L3G4200D(HWSPIDriver *driver) |
10 |
: driver(driver) { |
|
11 |
|
|
16 |
: driver(driver), |
|
17 |
udpsPerTic(175000), |
|
18 |
period_us(100000) { |
|
19 |
this->period_ms = this->period_us * 1e-3; |
|
20 |
this->period_st = US2ST(this->period_us); |
|
12 | 21 |
} |
13 | 22 |
|
14 | 23 |
L3G4200D::~L3G4200D() { |
... | ... | |
21 | 30 |
} |
22 | 31 |
|
23 | 32 |
msg_t L3G4200D::main() { |
24 |
|
|
25 |
this->setName("L3g4200d");
|
|
33 |
systime_t time = System::getTime(); |
|
34 |
this->setName("l3g4200d");
|
|
26 | 35 |
|
27 | 36 |
while (!this->shouldTerminate()) { |
37 |
time += this->period_st; |
|
28 | 38 |
|
29 | 39 |
updateSensorData(); |
40 |
calcAngular(); |
|
30 | 41 |
|
31 | 42 |
this->eventSource.broadcastFlags(1); |
32 | 43 |
|
33 |
this->waitAnyEventTimeout(ALL_EVENTS, MS2ST(200)); |
|
34 |
|
|
44 |
if (time >= System::getTime()) { |
|
45 |
chThdSleepUntil(time); |
|
46 |
} else { |
|
47 |
chprintf((BaseSequentialStream*) &SD1, "WARNING l3g4200d: Unable to keep track\r\n"); |
|
48 |
} |
|
35 | 49 |
} |
36 | 50 |
return RDY_OK; |
37 | 51 |
} |
... | ... | |
39 | 53 |
int16_t |
40 | 54 |
L3G4200D:: |
41 | 55 |
getAngularRate(const uint8_t axis) { |
42 |
|
|
43 | 56 |
return this->angularRate[axis]; |
57 |
} |
|
44 | 58 |
|
59 |
int32_t |
|
60 |
L3G4200D:: |
|
61 |
getAngularRate_udps(const uint8_t axis) { |
|
62 |
return uint32_t(this->angularRate[axis]) * this->udpsPerTic; |
|
63 |
} |
|
64 |
|
|
65 |
int32_t |
|
66 |
L3G4200D:: |
|
67 |
getAngular(const uint8_t axis) { |
|
68 |
return this->angular[axis]; |
|
69 |
} |
|
70 |
|
|
71 |
int32_t |
|
72 |
L3G4200D:: |
|
73 |
getAngular_ud(const uint8_t axis) { |
|
74 |
const int32_t angularRate_mdps = this->getAngularRate_udps(axis) * 1e-3; |
|
75 |
return angularRate_mdps * (this->integrationTic * this->period_ms); |
|
45 | 76 |
} |
46 | 77 |
|
78 |
void |
|
79 |
L3G4200D:: |
|
80 |
calcAngular() { |
|
81 |
// Need to check for overflow! |
|
82 |
++this->integrationTic; |
|
83 |
chSysLock(); |
|
84 |
this->angular[L3G4200D::AXIS_X] += int32_t(this->angularRate[L3G4200D::AXIS_X]); |
|
85 |
this->angular[L3G4200D::AXIS_Y] += int32_t(this->angularRate[L3G4200D::AXIS_Y]); |
|
86 |
this->angular[L3G4200D::AXIS_Z] += int32_t(this->angularRate[L3G4200D::AXIS_Z]); |
|
87 |
chSysUnlock(); |
|
88 |
} |
|
89 |
|
|
90 |
// TODO: Outsource, so that everyone who needs this has an own instance of the integrator |
|
91 |
void |
|
92 |
L3G4200D:: |
|
93 |
angularReset() { |
|
94 |
this->angular[L3G4200D::AXIS_X] = 0; |
|
95 |
this->angular[L3G4200D::AXIS_Y] = 0; |
|
96 |
this->angular[L3G4200D::AXIS_Z] = 0; |
|
97 |
this->integrationTic = 0; |
|
98 |
} |
|
99 |
|
|
100 |
|
|
47 | 101 |
void L3G4200D::updateSensorData() { |
48 | 102 |
|
49 | 103 |
const size_t buffer_size = offsetof(L3G4200D::registers, OUT_Z) |
... | ... | |
62 | 116 |
// assemble data |
63 | 117 |
sreg = buffer[1]; |
64 | 118 |
|
119 |
chSysLock(); |
|
65 | 120 |
if (sreg & L3G4200D::XDA) |
66 | 121 |
this->angularRate[L3G4200D::AXIS_X] = (buffer[3] << 8) + buffer[2]; |
67 | 122 |
|
... | ... | |
70 | 125 |
|
71 | 126 |
if (sreg & L3G4200D::ZDA) |
72 | 127 |
this->angularRate[L3G4200D::AXIS_Z] = (buffer[7] << 8) + buffer[6]; |
73 |
|
|
128 |
chSysUnlock(); |
|
74 | 129 |
} |
75 | 130 |
|
76 | 131 |
msg_t L3G4200D::configure(const L3G4200DConfig *config) { |
... | ... | |
95 | 150 |
buffer[5] = config->ctrl5; |
96 | 151 |
this->driver->write(buffer, 6); |
97 | 152 |
|
153 |
// Handle the new update time |
|
154 |
switch(config->ctrl1 & L3G4200D::DR_MASK) { |
|
155 |
case L3G4200D::DR_100_HZ: this->period_us = 10000; break; |
|
156 |
case L3G4200D::DR_200_HZ: this->period_us = 5000; break; |
|
157 |
case L3G4200D::DR_400_HZ: this->period_us = 2500; break; |
|
158 |
case L3G4200D::DR_800_HZ: this->period_us = 1250; break; |
|
159 |
} |
|
160 |
this->period_st = US2ST(this->period_st); |
|
161 |
|
|
162 |
// Handle the new full scale |
|
163 |
switch(config->ctrl1 & L3G4200D::FS_MASK) { |
|
164 |
case L3G4200D::FS_250_DPS: this->udpsPerTic = 8750; break; |
|
165 |
case L3G4200D::FS_500_DPS: this->udpsPerTic = 17500; break; |
|
166 |
case L3G4200D::FS_2000_DPS: this->udpsPerTic = 70000; break; |
|
167 |
} |
|
168 |
|
|
169 |
// Reset the integration |
|
170 |
this->angularReset(); |
|
171 |
|
|
98 | 172 |
return RDY_OK; |
99 | 173 |
|
100 | 174 |
} |
components/input/mpr121.cpp | ||
---|---|---|
1 | 1 |
#include <amiro/bus/i2c/I2CDriver.hpp> |
2 | 2 |
#include <amiro/input/mpr121.hpp> |
3 |
#include <amiro/Constants.h> |
|
3 | 4 |
|
4 | 5 |
namespace amiro { |
5 | 6 |
|
... | ... | |
171 | 172 |
|
172 | 173 |
this->eventSource.broadcastFlags(0); |
173 | 174 |
|
174 |
this->waitAnyEventTimeout(ALL_EVENTS, MS2ST(100));
|
|
175 |
this->waitAnyEventTimeout(ALL_EVENTS, CAN::UPDATE_PERIOD_MSEC);
|
|
175 | 176 |
} |
176 | 177 |
|
177 | 178 |
return RDY_OK; |
components/magneto/hmc5883l.cpp | ||
---|---|---|
5 | 5 |
#include <amiro/bus/i2c/I2CParams.hpp> |
6 | 6 |
#include <amiro/bus/i2c/I2CDriver.hpp> |
7 | 7 |
#include <amiro/magneto/hmc5883l.hpp> |
8 |
#include <amiro/Constants.h> |
|
8 | 9 |
|
9 | 10 |
using namespace chibios_rt; |
10 | 11 |
|
... | ... | |
50 | 51 |
|
51 | 52 |
this->eventSource.broadcastFlags(0); |
52 | 53 |
|
53 |
this->waitAnyEventTimeout(ALL_EVENTS, MS2ST(200));
|
|
54 |
this->waitAnyEventTimeout(ALL_EVENTS, CAN::UPDATE_PERIOD_MSEC);
|
|
54 | 55 |
} |
55 | 56 |
|
56 | 57 |
return RDY_OK; |
components/proximity/vcnl4020.cpp | ||
---|---|---|
6 | 6 |
#include <amiro/bus/i2c/I2CParams.hpp> |
7 | 7 |
#include <amiro/bus/i2c/I2CDriver.hpp> |
8 | 8 |
#include <amiro/proximity/vcnl4020.hpp> |
9 |
#include <amiro/Constants.h> |
|
9 | 10 |
|
10 | 11 |
using namespace chibios_rt; |
11 | 12 |
|
... | ... | |
107 | 108 |
|
108 | 109 |
this->eventSource.broadcastFlags(0); |
109 | 110 |
|
110 |
this->waitAnyEventTimeout(ALL_EVENTS, MS2ST(200));
|
|
111 |
this->waitAnyEventTimeout(ALL_EVENTS, CAN::UPDATE_PERIOD_MSEC);
|
|
111 | 112 |
} |
112 | 113 |
|
113 | 114 |
return RDY_OK; |
devices/DiWheelDrive/DiWheelDrive.cpp | ||
---|---|---|
148 | 148 |
for (int idx = 0; idx < 4; ++idx) |
149 | 149 |
this->proximityFloorValue[idx] = global.vcnl4020[idx].getProximityScaledWoOffset(); |
150 | 150 |
|
151 |
// Update magnetometer values |
|
152 |
for (uint8_t axis = 0; axis < 3; ++axis) { |
|
153 |
this->magnetometerValue[axis] = global.hmc5883l.getMagnetizationGauss(axis); |
|
154 |
} |
|
155 |
|
|
156 |
// Update gyroscope values |
|
157 |
for (uint8_t axis = 0; axis < 3; ++axis) { |
|
158 |
this->gyroscopeValue[axis] = global.l3g4200d.getAngularRate(axis); |
|
159 |
} |
|
160 |
|
|
151 | 161 |
return 0; |
152 | 162 |
} |
153 | 163 |
|
... | ... | |
164 | 174 |
|
165 | 175 |
// Send the valocites µm/s of the x axis and µrad/s around z axis: end |
166 | 176 |
// Send the odometry: start |
167 |
// BaseThread::sleep(MS2ST(10)); // Sleep, otherwise the cognition-board wont receive all messages
|
|
177 |
BaseThread::sleep(US2ST(10)); // Use to sleep for 10 CAN cycle (@1Mbit), otherwise the cognition-board might not receive all messagee
|
|
168 | 178 |
// Set the frame id |
169 | 179 |
frame.SID = 0; |
170 | 180 |
this->encodeDeviceId(&frame, CAN::ODOMETRY_ID); |
... | ... | |
181 | 191 |
|
182 | 192 |
// Send the odometry: end |
183 | 193 |
// Send the proximity values of the floor: start |
184 |
// BaseThread::sleep(MS2ST(10)); // Sleep, otherwise the cognition-board wont receive all messages
|
|
194 |
BaseThread::sleep(US2ST(10)); // Use to sleep for 10 CAN cycle (@1Mbit), otherwise the cognition-board might not receive all messagee
|
|
185 | 195 |
// Set the frame id |
186 | 196 |
frame.SID = 0; |
187 | 197 |
this->encodeDeviceId(&frame, CAN::PROXIMITY_FLOOR_ID); |
... | ... | |
192 | 202 |
frame.DLC = 8; |
193 | 203 |
this->transmitMessage(&frame); |
194 | 204 |
|
205 |
// Send the magnetometer data |
|
206 |
for (uint8_t axis = 0; axis < 3; ++axis) { |
|
207 |
frame.SID = 0; |
|
208 |
this->encodeDeviceId(&frame, CAN::MAGNETOMETER_X_ID + axis); // Y- and Z-axis have according IDs |
|
209 |
frame.data32[0] = this->magnetometerValue[axis]; |
|
210 |
frame.DLC = 4; |
|
211 |
this->transmitMessage(&frame); |
|
212 |
} |
|
213 |
|
|
214 |
// Send gyroscope data |
|
215 |
frame.SID = 0; |
|
216 |
this->encodeDeviceId(&frame, CAN::GYROSCOPE_ID); |
|
217 |
frame.data16[0] = this->gyroscopeValue[0]; |
|
218 |
frame.data16[1] = this->gyroscopeValue[1]; |
|
219 |
frame.data16[2] = this->gyroscopeValue[2]; |
|
220 |
frame.DLC = 6; |
|
221 |
this->transmitMessage(&frame); |
|
222 |
|
|
195 | 223 |
// Send the board ID (board ID of DiWheelDrive = Robot ID) |
196 | 224 |
if (this->bcCounter % 10 == 0) { |
197 | 225 |
frame.SID = 0; |
devices/DiWheelDrive/global.hpp | ||
---|---|---|
55 | 55 |
/* command */ VCNL4020::ALS_EN | VCNL4020::PROX_EN | VCNL4020::SELFTIMED_EN, |
56 | 56 |
/* ambient parameter */ VCNL4020::AMBIENT_RATE_2 | VCNL4020::AMBIENT_AUTO_OFFSET | VCNL4020::AMBIENT_AVG_32, |
57 | 57 |
/* IR LED current [mA] */ 200u, |
58 |
/* proximity rate */ VCNL4020::PROX_RATE_7_8125
|
|
58 |
/* proximity rate */ VCNL4020::PROX_RATE_125 |
|
59 | 59 |
}; |
60 | 60 |
|
61 | 61 |
/** |
... | ... | |
190 | 190 |
increments(&QEID3, &QEID4), |
191 | 191 |
motorcontrol(&PWMD2, &increments, GPIOB, GPIOB_POWER_EN, &memory), |
192 | 192 |
distcontrol(&motorcontrol, &increments), |
193 |
odometry(&increments), |
|
193 |
odometry(&increments, &l3g4200d),
|
|
194 | 194 |
sercanmux1(&SD1, &CAND1, CAN::DI_WHEEL_DRIVE_ID), |
195 | 195 |
robot(&CAND1), |
196 | 196 |
userThread() |
devices/DiWheelDrive/main.cpp | ||
---|---|---|
792 | 792 |
*/ |
793 | 793 |
BaseThread::sleep(MS2ST(2000)); |
794 | 794 |
|
795 |
boardClearI2CBus(GPIOB_COMPASS_SCL); |
|
796 |
boardClearI2CBus(GPIOB_IR_SCL); |
|
795 |
boardClearI2CBus(GPIOB_COMPASS_SCL, GPIOB_COMPASS_SDA);
|
|
796 |
boardClearI2CBus(GPIOB_IR_SCL, GPIOB_IR_SDA);
|
|
797 | 797 |
|
798 | 798 |
global.HW_I2C1.start(&global.i2c1_config); |
799 | 799 |
global.HW_I2C2.start(&global.i2c2_config); |
devices/DiWheelDrive/userthread.cpp | ||
---|---|---|
76 | 76 |
|
77 | 77 |
const int blackStartFalling = 0x1000; // Where the black curve starts falling |
78 | 78 |
const int blackOff = 0x1800; // Where no more black is detected |
79 |
const int whiteStartRising = 0x4000; // Where the white curve starts rising
|
|
80 |
const int whiteOn = 0x8000; // Where the white curve has reached the maximum value
|
|
79 |
const int whiteStartRising = 0x2800; // Where the white curve starts rising
|
|
80 |
const int whiteOn = 0x6000; // Where the white curve has reached the maximum value
|
|
81 | 81 |
const int greyMax = (whiteOn + blackStartFalling) / 2; // Where grey has its maximum |
82 | 82 |
const int greyStartRising = blackStartFalling; // Where grey starts rising |
83 | 83 |
const int greyOff = whiteOn; // Where grey is completely off again |
... | ... | |
188 | 188 |
// Get a crisp output for the steering commands |
189 | 189 |
void defuzzyfication(colorMember (&member)[4], int (&rpmFuzzyCtrl)[2]) { |
190 | 190 |
|
191 |
if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == BLACK && |
|
192 |
member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == BLACK) { |
|
191 |
// all sensors are equal |
|
192 |
if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == member[constants::DiWheelDrive::PROX_FRONT_LEFT] && |
|
193 |
member[constants::DiWheelDrive::PROX_FRONT_LEFT] == member[constants::DiWheelDrive::PROX_FRONT_RIGHT] && |
|
194 |
member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == member[constants::DiWheelDrive::PROX_WHEEL_RIGHT]) { |
|
195 |
// something is wrong -> stop |
|
196 |
copyRpmSpeed(rpmHalt, rpmFuzzyCtrl); |
|
197 |
// both front sensor detect a line |
|
198 |
} else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == BLACK && |
|
199 |
member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == BLACK) { |
|
193 | 200 |
// straight |
194 | 201 |
copyRpmSpeed(rpmForward, rpmFuzzyCtrl); |
202 |
// exact one front sensor detects a line |
|
195 | 203 |
} else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == BLACK || |
196 | 204 |
member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == BLACK) { |
197 | 205 |
// soft correction |
198 |
if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == GREY) |
|
206 |
if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == GREY) {
|
|
199 | 207 |
// soft right |
200 | 208 |
copyRpmSpeed(rpmSoftRight, rpmFuzzyCtrl); |
201 |
else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == WHITE)
|
|
209 |
} else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == WHITE) {
|
|
202 | 210 |
// hard right |
203 | 211 |
copyRpmSpeed(rpmHardRight, rpmFuzzyCtrl); |
204 |
else if (member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == GREY)
|
|
212 |
} else if (member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == GREY) {
|
|
205 | 213 |
// soft left |
206 | 214 |
copyRpmSpeed(rpmSoftLeft, rpmFuzzyCtrl); |
207 |
else if (member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == WHITE)
|
|
215 |
} else if (member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == WHITE) {
|
|
208 | 216 |
// hard left |
209 | 217 |
copyRpmSpeed(rpmHardLeft, rpmFuzzyCtrl); |
210 |
} else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == GREY || |
|
218 |
} |
|
219 |
// both wheel sensors detect a line |
|
220 |
} else if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == BLACK && |
|
221 |
member[constants::DiWheelDrive::PROX_WHEEL_RIGHT] == BLACK) { |
|
222 |
// something is wrong -> stop |
|
223 |
copyRpmSpeed(rpmHalt, rpmFuzzyCtrl); |
|
224 |
// exactly one wheel sensor detects a line |
|
225 |
} else if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == BLACK || |
|
226 |
member[constants::DiWheelDrive::PROX_WHEEL_RIGHT] == BLACK) { |
|
227 |
if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == BLACK) { |
|
228 |
// turn left |
|
229 |
copyRpmSpeed(rpmTurnLeft, rpmFuzzyCtrl); |
|
230 |
} else if (member[constants::DiWheelDrive::PROX_WHEEL_RIGHT] == BLACK) { |
|
231 |
// turn right |
|
232 |
copyRpmSpeed(rpmTurnRight, rpmFuzzyCtrl); |
|
233 |
} |
|
234 |
// both front sensors may detect a line |
|
235 |
} else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == GREY && |
|
211 | 236 |
member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == GREY) { |
212 |
if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == WHITE) |
|
237 |
if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == GREY) { |
|
238 |
// turn left |
|
239 |
copyRpmSpeed(rpmTurnLeft, rpmFuzzyCtrl); |
|
240 |
} else if (member[constants::DiWheelDrive::PROX_WHEEL_RIGHT] == GREY) { |
|
213 | 241 |
// turn right |
214 | 242 |
copyRpmSpeed(rpmTurnRight, rpmFuzzyCtrl); |
215 |
else if (member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == WHITE) |
|
243 |
} |
|
244 |
// exactly one front sensor may detect a line |
|
245 |
} else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == GREY || |
|
246 |
member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == GREY) { |
|
247 |
if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == GREY) { |
|
216 | 248 |
// turn left |
217 | 249 |
copyRpmSpeed(rpmTurnLeft, rpmFuzzyCtrl); |
218 |
else |
|
219 |
// go straight |
|
220 |
copyRpmSpeed(rpmForward, rpmFuzzyCtrl); |
|
221 |
} else if (member[constants::DiWheelDrive::PROX_FRONT_LEFT] == WHITE && |
|
222 |
member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == WHITE) { |
|
223 |
// go straight and check wheel sensors |
|
224 |
if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] != WHITE) |
|
250 |
} else if (member[constants::DiWheelDrive::PROX_FRONT_RIGHT] == GREY) { |
|
251 |
// turn right |
|
252 |
copyRpmSpeed(rpmTurnRight, rpmFuzzyCtrl); |
|
253 |
} |
|
254 |
// both wheel sensors may detect a line |
|
255 |
} else if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == GREY && |
|
256 |
member[constants::DiWheelDrive::PROX_WHEEL_RIGHT] == GREY) { |
|
257 |
// something is wrong -> stop |
|
258 |
copyRpmSpeed(rpmHalt, rpmFuzzyCtrl); |
|
259 |
// exactly one wheel sensor may detect a line |
|
260 |
} else if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == GREY || |
|
261 |
member[constants::DiWheelDrive::PROX_WHEEL_RIGHT] == GREY) { |
|
262 |
if (member[constants::DiWheelDrive::PROX_WHEEL_LEFT] == GREY) { |
|
225 | 263 |
// turn left |
226 | 264 |
copyRpmSpeed(rpmTurnLeft, rpmFuzzyCtrl); |
227 |
else if (member[constants::DiWheelDrive::PROX_WHEEL_RIGHT] != WHITE)
|
|
265 |
} else if (member[constants::DiWheelDrive::PROX_WHEEL_RIGHT] == GREY) {
|
|
228 | 266 |
// turn right |
229 | 267 |
copyRpmSpeed(rpmTurnRight, rpmFuzzyCtrl); |
230 |
else |
|
231 |
// line is lost -> stop |
|
232 |
copyRpmSpeed(rpmHalt, rpmFuzzyCtrl); |
|
268 |
} |
|
269 |
// no sensor detects anything |
|
270 |
} else { |
|
271 |
// line is lost -> stop |
|
272 |
copyRpmSpeed(rpmHalt, rpmFuzzyCtrl); |
|
233 | 273 |
} |
234 | 274 |
|
235 | 275 |
return; |
... | ... | |
371 | 411 |
setRpmSpeed(rpmFuzzyCtrl); |
372 | 412 |
} |
373 | 413 |
|
374 |
this->sleep(MS2ST(100));
|
|
414 |
this->sleep(MS2ST(10)); |
|
375 | 415 |
} |
376 | 416 |
|
377 | 417 |
return RDY_OK; |
devices/LightRing/main.cpp | ||
---|---|---|
514 | 514 |
|
515 | 515 |
extStart(&EXTD1, &extcfg); |
516 | 516 |
|
517 |
boardClearI2CBus(GPIOB_MEM_SCL); |
|
517 |
boardClearI2CBus(GPIOB_MEM_SCL, GPIOB_MEM_SDA);
|
|
518 | 518 |
|
519 | 519 |
global.HW_I2C2.start(&global.i2c2_config); |
520 | 520 |
|
devices/PowerManagement/PowerManagement.cpp | ||
---|---|---|
133 | 133 |
frame.data16[0] = this->proximityRingValue[i]; |
134 | 134 |
frame.DLC = 2; |
135 | 135 |
this->transmitMessage(&frame); |
136 |
// HACK This is a first workaround (do wrapping of 4 sensors, better timing than 10 ms in sleep) |
|
137 |
// I choosed 10 ms, because 10 ms x 8 = 80 ms < 125 ms which is the updaterate CAN::UPDATE_PERIOD_MSEC |
|
138 |
BaseThread::sleep(MS2ST(10)); // Sleep, otherwise the cognition-board wont receive all messages |
|
136 |
BaseThread::sleep(US2ST(10)); // Use to sleep for 10 CAN cycle (@1Mbit), otherwise the cognition-board might not receive all messagee |
|
139 | 137 |
} |
140 | 138 |
++this->bc_counter; |
141 | 139 |
} |
devices/PowerManagement/global.hpp | ||
---|---|---|
55 | 55 |
|
56 | 56 |
I2CConfig i2c1_config{ |
57 | 57 |
/* I2C mode */ OPMODE_I2C, |
58 |
/* frequency */ 200000,
|
|
59 |
/* I2C fast mode duty cycle */ FAST_DUTY_CYCLE_2
|
|
58 |
/* frequency */ 100000,
|
|
59 |
/* I2C fast mode duty cycle */ STD_DUTY_CYCLE
|
|
60 | 60 |
}; |
61 | 61 |
I2CConfig i2c2_config{ |
62 | 62 |
/* I2C mode */ OPMODE_I2C, |
63 |
/* frequency */ 200000,
|
|
64 |
/* I2C fast mode duty cycle */ FAST_DUTY_CYCLE_2
|
|
63 |
/* frequency */ 100000,
|
|
64 |
/* I2C fast mode duty cycle */ STD_DUTY_CYCLE
|
|
65 | 65 |
}; |
66 | 66 |
|
67 | 67 |
VCNL4020::VCNL4020Config vcnl4020_config{ |
68 | 68 |
/* command */ VCNL4020::ALS_EN | VCNL4020::PROX_EN | VCNL4020::SELFTIMED_EN, |
69 | 69 |
/* ambient parameter */ VCNL4020::AMBIENT_RATE_2 | VCNL4020::AMBIENT_AUTO_OFFSET | VCNL4020::AMBIENT_AVG_32, |
70 | 70 |
/* IR LED current [mA] */ 200u, |
71 |
/* proximity rate */ VCNL4020::PROX_RATE_7_8125
|
|
71 |
/* proximity rate */ VCNL4020::PROX_RATE_125 |
|
72 | 72 |
}; |
73 | 73 |
|
74 | 74 |
adcsample_t adc1_buffer[1]; |
devices/PowerManagement/main.cpp | ||
---|---|---|
976 | 976 |
|
977 | 977 |
extStart(&EXTD1, &extcfg); |
978 | 978 |
|
979 |
boardClearI2CBus(GPIOB_GAUGE_SCL1); |
|
980 |
boardClearI2CBus(GPIOB_GAUGE_SCL2); |
|
979 |
boardClearI2CBus(GPIOB_GAUGE_SCL1, GPIOB_GAUGE_SDA1);
|
|
980 |
boardClearI2CBus(GPIOB_GAUGE_SCL2, GPIOB_GAUGE_SDA2);
|
|
981 | 981 |
|
982 | 982 |
global.HW_I2C1.start(&global.i2c1_config); |
983 | 983 |
global.HW_I2C2.start(&global.i2c2_config); |
984 | 984 |
|
985 |
uint16_t i2c_test = 0; |
|
986 |
while (global.ina219[INA_VIO18].readRegister(INA219::Driver::REG_BUS_VOLTAGE, i2c_test) != RDY_OK) { |
|
987 |
chprintf((BaseSequentialStream*)&global.sercanmux1, "I2C #1 stalled! trying to clear the bus... (this will take 20 seconds)\n"); |
|
988 |
boardWriteLed(1); |
|
989 |
boardResetBQ27500I2C(GPIOB_GAUGE_SCL2, GPIOB_GAUGE_SDA2); |
|
990 |
boardWriteLed(0); |
|
991 |
} |
|
992 |
while (global.ina219[INA_VDD].readRegister(INA219::Driver::REG_BUS_VOLTAGE, i2c_test) != RDY_OK) { |
|
993 |
chprintf((BaseSequentialStream*)&global.sercanmux1, "I2C #2 stalled! trying to clear the bus... (this will take 20 seconds)\n"); |
|
994 |
boardWriteLed(1); |
|
995 |
boardResetBQ27500I2C(GPIOB_GAUGE_SCL1, GPIOB_GAUGE_SDA1); |
|
996 |
boardWriteLed(0); |
|
997 |
} |
|
998 |
|
|
985 | 999 |
global.memory.init(); |
986 | 1000 |
uint8_t i = 0; |
987 | 1001 |
if (global.memory.getBoardId(&i) == fileSystemIo::FileSystemIoBase::OK) { |
devices/PowerManagement/userthread.cpp | ||
---|---|---|
14 | 14 |
bool running; |
15 | 15 |
|
16 | 16 |
uint16_t constexpr proxThresholdLow = 0x0000; |
17 |
uint16_t constexpr proxThresholdHigh = 0x2000;
|
|
17 |
uint16_t constexpr proxThresholdHigh = 0x1000;
|
|
18 | 18 |
uint16_t constexpr proxRange = proxThresholdHigh - proxThresholdLow; |
19 | 19 |
|
20 | 20 |
std::array< std::array<float, 2>, 8> constexpr namMatrix = { |
... | ... | |
28 | 28 |
std::array<float, 2>/* ESE */{ 0.25f, 0.25f}, |
29 | 29 |
std::array<float, 2>/* SSE */{ 0.00f, 0.00f} |
30 | 30 |
}; |
31 |
uint32_t constexpr baseTranslation = 50e3; // 2cm/s
|
|
31 |
uint32_t constexpr baseTranslation = 100e3; // 2cm/s
|
|
32 | 32 |
uint32_t constexpr baseRotation = 1e6; // 1rad/s |
33 | 33 |
types::kinematic constexpr defaultKinematic = { |
34 | 34 |
/* x [µm/s] */ baseTranslation, |
... | ... | |
161 | 161 |
global.robot.setTargetSpeed(kinematic); |
162 | 162 |
} |
163 | 163 |
|
164 |
this->sleep(MS2ST(100));
|
|
164 |
this->sleep(MS2ST(10)); |
|
165 | 165 |
} |
166 | 166 |
|
167 | 167 |
return RDY_OK; |
devices/flash.mk | ||
---|---|---|
4 | 4 |
PowerManagement := 2 |
5 | 5 |
LightRing := 3 |
6 | 6 |
|
7 |
SERIALBOOT ?= SerialBoot |
|
7 |
SERIALBOOT ?= $(dir $(abspath $(lastword $(MAKEFILE_LIST))))../../amiro-blt/Host/Source/SerialBoot/build/SerialBoot |
|
8 |
$(info $(SERIALBOOT)) |
|
9 |
|
|
8 | 10 |
ifeq ($(OS),Windows_NT) |
9 | 11 |
SERIALBOOT_PORT ?= COM4 |
10 | 12 |
else |
... | ... | |
17 | 19 |
#SERIALBOOT_BT_ADDR ?= 00:00:00:00:00:00 |
18 | 20 |
SERIALBOOT_BT_ADDR ?= 00:07:80:44:23:F9 |
19 | 21 |
|
20 |
|
|
21 | 22 |
ifdef PROJECT |
22 | 23 |
DEVICES := |
23 | 24 |
FLASHFILE = build/$(PROJECT).srec |
include/amiro/Constants.h | ||
---|---|---|
37 | 37 |
|
38 | 38 |
namespace CAN { |
39 | 39 |
|
40 |
const uint32_t UPDATE_PERIOD_MSEC = MS2ST(125);
|
|
40 |
const uint32_t UPDATE_PERIOD_MSEC = US2ST(62500); // 16 Hz
|
|
41 | 41 |
|
42 | 42 |
const uint32_t PERIODIC_TIMER_ID = 1; |
43 | 43 |
const uint32_t RECEIVED_ID = 2; |
... | ... | |
54 | 54 |
const uint32_t LIGHT_RING_ID = 3; |
55 | 55 |
const uint32_t COGNITION = 4; |
56 | 56 |
|
57 |
|
|
57 |
const uint32_t MAGNETOMETER_X_ID = 0x54; |
|
58 |
const uint32_t MAGNETOMETER_Y_ID = 0x55; |
|
59 |
const uint32_t MAGNETOMETER_Z_ID = 0x56; |
|
60 |
const uint32_t GYROSCOPE_ID = 0x58; |
|
58 | 61 |
const uint32_t PROXIMITY_FLOOR_ID = 0x51; |
59 | 62 |
const uint32_t ODOMETRY_ID = 0x50; |
60 | 63 |
const uint32_t BRIGHTNESS_ID = 0x40; |
include/amiro/ControllerAreaNetworkRx.h | ||
---|---|---|
20 | 20 |
types::position getOdometry(); |
21 | 21 |
types::power_status& getPowerStatus(); |
22 | 22 |
uint8_t getRobotID(); |
23 |
int32_t getMagnetometerValue(int axis); |
|
24 |
int16_t getGyroscopeValue(int axis); |
|
23 | 25 |
|
24 | 26 |
void calibrateProximityRingValues(); |
25 | 27 |
void calibrateProximityFloorValues(); |
... | ... | |
38 | 40 |
uint16_t proximityRingValue[8]; |
39 | 41 |
int actualSpeed[2]; |
40 | 42 |
uint16_t proximityFloorValue[4]; |
43 |
int32_t magnetometerValue[3]; |
|
44 |
int16_t gyroscopeValue[3]; |
|
41 | 45 |
types::position robotPosition; |
42 | 46 |
types::power_status powerStatus; |
43 | 47 |
uint8_t robotId; |
include/amiro/Odometry.h | ||
---|---|---|
2 | 2 |
#define AMIRO_ODOMETRY_H_ |
3 | 3 |
|
4 | 4 |
#include <amiro/MotorControl.h> |
5 |
#include <amiro/gyro/l3g4200d.hpp> |
|
5 | 6 |
|
6 | 7 |
#include <Types.h> // types::position |
7 | 8 |
|
... | ... | |
13 | 14 |
* Constructor |
14 | 15 |
* |
15 | 16 |
* @param mi object for retrieving the motor increments of the qei |
17 |
* @param gyro object for retrieving the gyroscope data |
|
18 |
* @param mc object for retrieving calibration parameters |
|
16 | 19 |
*/ |
17 |
Odometry(MotorIncrements* mi); |
|
20 |
Odometry(MotorIncrements* mi, L3G4200D* gyroscope);
|
|
18 | 21 |
|
19 | 22 |
/** |
20 | 23 |
* Set the position of the roboter |
... | ... | |
74 | 77 |
*/ |
75 | 78 |
void updateOdometry(); |
76 | 79 |
|
77 |
MotorIncrements* motorIncrements; |
|
80 |
MotorIncrements* motorIncrements; // QEI driver |
|
81 |
L3G4200D* gyro; // Gyroscope driver |
|
78 | 82 |
chibios_rt::EvtSource eventSource; |
79 | 83 |
const unsigned int period; |
80 | 84 |
int incrementsPerRevolution; |
include/amiro/gyro/l3g4200d.hpp | ||
---|---|---|
15 | 15 |
DR_200_HZ = 0x40, |
16 | 16 |
DR_400_HZ = 0x80, |
17 | 17 |
DR_800_HZ = 0xC0, |
18 |
DR_MASK = 0xC0, |
|
18 | 19 |
}; |
19 | 20 |
enum { |
20 | 21 |
BW_12_5 = 0x00, |
... | ... | |
25 | 26 |
BW_50 = 0x20, |
26 | 27 |
BW_70 = 0x30, |
27 | 28 |
BW_110 = 0x30, |
29 |
BW_MASK = 0x30, |
|
28 | 30 |
}; |
29 | 31 |
enum { |
30 |
PD = 0x08, |
|
31 |
ZEN = 0x04, |
|
32 |
YEN = 0x02, |
|
33 |
XEN = 0x01, |
|
32 |
PD = 0x08, |
|
33 |
ZEN = 0x04, |
|
34 |
YEN = 0x02, |
|
35 |
XEN = 0x01, |
|
36 |
EN_MASK = 0x0F, |
|
34 | 37 |
}; |
35 | 38 |
enum { |
36 | 39 |
HPM_NORMAL_RST = 0x00, |
... | ... | |
73 | 76 |
ST_EN = 0x02, |
74 | 77 |
SIM_3W = 0x01, |
75 | 78 |
SIM_4W = 0x00, |
79 |
FS_MASK = 0x20, |
|
76 | 80 |
}; |
77 | 81 |
enum { |
78 | 82 |
BOOT = 0x80, |
... | ... | |
224 | 228 |
chibios_rt::EvtSource* getEventSource(); |
225 | 229 |
msg_t configure(const L3G4200DConfig* config); |
226 | 230 |
int16_t angularRate[AXIS_Z - AXIS_X + 1]; |
231 |
int32_t angular[AXIS_Z - AXIS_X + 1]; |
|
227 | 232 |
|
228 | 233 |
int16_t getAngularRate(const uint8_t axis); |
234 |
|
|
235 |
int32_t getAngularRate_udps(const uint8_t axis); |
|
236 |
int32_t getAngular(const uint8_t axis); |
|
237 |
int32_t getAngular_ud(const uint8_t axis); |
|
238 |
void angularReset(); |
|
229 | 239 |
|
230 | 240 |
|
231 | 241 |
/** |
... | ... | |
240 | 250 |
|
241 | 251 |
private: |
242 | 252 |
inline void updateSensorData(); |
253 |
inline void calcAngular(); |
|
243 | 254 |
|
244 | 255 |
private: |
245 | 256 |
|
246 | 257 |
HWSPIDriver* driver; |
247 | 258 |
chibios_rt::EvtSource eventSource; |
259 |
uint32_t integrationTic; |
|
260 |
uint32_t udpsPerTic; // Resolution: Micro-degree-per-second per digit |
|
261 |
uint32_t period_us; |
|
262 |
uint32_t period_ms; |
|
263 |
systime_t period_st; |
|
248 | 264 |
|
249 | 265 |
}; |
250 | 266 |
|
include/amiro/power/ina219.hpp | ||
---|---|---|
140 | 140 |
Status() {bus_voltage.value = 0; power = 0;} |
141 | 141 |
}; |
142 | 142 |
|
143 |
public: |
|
143 | 144 |
enum RegisterAddress { |
144 | 145 |
REG_CONFIGURATION = 0x00u, |
145 | 146 |
REG_SHUNT_VOLTAGE = 0x01u, |
... | ... | |
149 | 150 |
REG_CALIBRATION = 0x05u |
150 | 151 |
}; |
151 | 152 |
|
153 |
private: |
|
152 | 154 |
enum RegisterMask { |
153 | 155 |
MASK_CONFIGURATION = 0x3FFFu, |
154 | 156 |
MASK_CALIBRATION = 0xFFFEu, |
... | ... | |
204 | 206 |
|
205 | 207 |
uint8_t reset(); |
206 | 208 |
|
207 |
protected: |
|
209 |
protected:
|
|
208 | 210 |
virtual msg_t main(void); |
209 | 211 |
|
210 |
private:
|
|
212 |
public:
|
|
211 | 213 |
msg_t readRegister(const RegisterAddress reg, uint16_t& dst); |
212 | 214 |
msg_t writeRegister(const RegisterAddress reg, const uint16_t& val); |
213 | 215 |
|
216 |
private: |
|
214 | 217 |
static inline INA219::BusVoltage busVoltageReg2uV(const INA219::Driver::BusVoltage reg_val) |
215 | 218 |
{ |
216 | 219 |
INA219::BusVoltage bus_voltage; |
Also available in: Unified diff