amiro-os / devices / PowerManagement / userthread.cpp @ 2f3e64c4
History | View | Annotate | Download (4.788 KB)
1 |
#include "userthread.h" |
---|---|
2 |
|
3 |
#include "global.hpp" |
4 |
#include <array> |
5 |
#include <chprintf.h> |
6 |
|
7 |
using namespace amiro; |
8 |
|
9 |
extern Global global;
|
10 |
|
11 |
uint16_t touch; |
12 |
std::array<uint16_t, 8> proximity;
|
13 |
std::array<float, 8> proxNormalized; |
14 |
|
15 |
bool running;
|
16 |
|
17 |
uint16_t constexpr proxThresholdLow = 0x0000;
|
18 |
uint16_t constexpr proxThresholdHigh = 0x1000;
|
19 |
uint16_t constexpr proxRange = proxThresholdHigh - proxThresholdLow; |
20 |
|
21 |
std::array< std::array<float, 2>, 8> constexpr namMatrix = { |
22 |
/* x w_z */
|
23 |
std::array<float, 2>/* SSW */{ 0.00f, 0.00f}, |
24 |
std::array<float, 2>/* WSW */{ 0.25f, -0.25f}, |
25 |
std::array<float, 2>/* WNW */{-0.75f, -0.50f}, |
26 |
std::array<float, 2>/* NNW */{-0.75f, -1.00f}, |
27 |
std::array<float, 2>/* NNE */{-0.75f, 1.00f}, |
28 |
std::array<float, 2>/* ENE */{-0.75f, 0.50f}, |
29 |
std::array<float, 2>/* ESE */{ 0.25f, 0.25f}, |
30 |
std::array<float, 2>/* SSE */{ 0.00f, 0.00f} |
31 |
}; |
32 |
uint32_t constexpr baseTranslation = 100e3; // 2cm/s |
33 |
uint32_t constexpr baseRotation = 1e6; // 1rad/s |
34 |
types::kinematic constexpr defaultKinematic = { |
35 |
/* x [µm/s] */ baseTranslation,
|
36 |
/* y [µm/s] */ 0, |
37 |
/* z [µm/s] */ 0, |
38 |
/* w_x [µrad/s] */ 0, |
39 |
/* w_y [µrad/s] */ 0, |
40 |
/* w_z [µrad/s] */ 0 |
41 |
}; |
42 |
|
43 |
|
44 |
|
45 |
inline uint8_t ProxId2LedId(const uint8_t proxId) { |
46 |
return (proxId < 4) ? proxId+4 : proxId-4; |
47 |
} |
48 |
|
49 |
Color Prox2Color(const float prox) { |
50 |
float p = 0.0f; |
51 |
if (prox < 0.5f) { |
52 |
p = 2.0f * prox; |
53 |
return Color(0x00, p*0xFF, (1.0f-p)*0xFF); |
54 |
} else {
|
55 |
p = 2.0f * (prox - 0.5f); |
56 |
return Color(p*0xFF, (1.0f-p)*0xFF, 0x00); |
57 |
} |
58 |
} |
59 |
|
60 |
UserThread::UserThread() : |
61 |
chibios_rt::BaseStaticThread<USER_THREAD_STACK_SIZE>() |
62 |
{ |
63 |
} |
64 |
|
65 |
UserThread::~UserThread() |
66 |
{ |
67 |
} |
68 |
|
69 |
msg_t |
70 |
UserThread::main() |
71 |
{ |
72 |
uint8_t sensor = 0;
|
73 |
float factor_x = 0.0f; |
74 |
float factor_wz = 0.0f; |
75 |
types::kinematic kinematic = defaultKinematic; |
76 |
|
77 |
for (uint8_t led = 0; led < 8; ++led) { |
78 |
global.robot.setLightColor(led, Color(Color::BLACK)); |
79 |
} |
80 |
running = false;
|
81 |
|
82 |
while (!this->shouldTerminate()) |
83 |
{ |
84 |
/*
|
85 |
* read touch sensor values
|
86 |
*/
|
87 |
touch = global.mpr121.getButtonStatus(); |
88 |
|
89 |
/*
|
90 |
* evaluate touch input
|
91 |
*/
|
92 |
if (touch == 0x0F) { |
93 |
if (running) {
|
94 |
// stop the robot
|
95 |
running = false;
|
96 |
kinematic = {0, 0, 0, 0, 0, 0}; |
97 |
global.robot.setTargetSpeed(kinematic); |
98 |
} else {
|
99 |
// start the robot
|
100 |
running = true;
|
101 |
} |
102 |
|
103 |
// set all LEDs to white for one second
|
104 |
for (uint8_t led = 0; led < 8; ++led) { |
105 |
global.robot.setLightColor(led, Color(Color::WHITE)); |
106 |
} |
107 |
this->sleep(MS2ST(1000)); |
108 |
for (uint8_t led = 0; led < 8; ++led) { |
109 |
global.robot.setLightColor(led, Color(Color::BLACK)); |
110 |
} |
111 |
} |
112 |
|
113 |
if (running) {
|
114 |
/*
|
115 |
* read proximity values
|
116 |
*/
|
117 |
for (sensor = 0; sensor < 8; ++sensor) { |
118 |
proximity[sensor] = global.vcnl4020[sensor].getProximityScaledWoOffset(); |
119 |
//proxNormalized[sensor] += 2.0f * (proxNormalized[sensor] * (1.0f - proxNormalized[sensor])); // non linearity
|
120 |
} |
121 |
|
122 |
/*
|
123 |
* normalize proximity values
|
124 |
*/
|
125 |
for (sensor = 0; sensor < 8; ++sensor) { |
126 |
register uint16_t prox = proximity[sensor];
|
127 |
// limit to high treshold
|
128 |
if (prox > proxThresholdHigh)
|
129 |
prox = proxThresholdHigh; |
130 |
// limit to low threshold
|
131 |
else if (prox < proxThresholdLow) |
132 |
prox = proxThresholdLow; |
133 |
// apply low threshold
|
134 |
prox -= proxThresholdLow; |
135 |
// normalize to [0, 1]
|
136 |
proxNormalized[sensor] = float(prox) / float(proxRange); |
137 |
} |
138 |
|
139 |
/*
|
140 |
* map the sensor values to the top LEDs
|
141 |
*/
|
142 |
for (sensor = 0; sensor < 8; ++sensor) { |
143 |
global.robot.setLightColor(ProxId2LedId(sensor), Prox2Color(proxNormalized[sensor])); |
144 |
} |
145 |
|
146 |
/*
|
147 |
* evaluate NAM
|
148 |
*/
|
149 |
factor_x = 0.0f; |
150 |
factor_wz = 0.0f; |
151 |
for (sensor = 0; sensor < 8; ++sensor) { |
152 |
factor_x += proxNormalized[sensor] * namMatrix[sensor][0];
|
153 |
factor_wz += proxNormalized[sensor] * namMatrix[sensor][1];
|
154 |
} |
155 |
|
156 |
/*
|
157 |
* set motor commands
|
158 |
*/
|
159 |
kinematic = defaultKinematic; |
160 |
kinematic.x += (factor_x * baseTranslation) + 0.5f; |
161 |
kinematic.w_z += (factor_wz * baseRotation) + 0.5f; |
162 |
global.robot.setTargetSpeed(kinematic); |
163 |
} |
164 |
|
165 |
this->sleep(MS2ST(10)); |
166 |
} |
167 |
|
168 |
return RDY_OK;
|
169 |
} |
170 |
|