amiro-os / devices / DiWheelDrive / userthread.cpp @ f3972840
History | View | Annotate | Download (7.311 KB)
1 | 58fe0e0b | Thomas Schöpping | #include "userthread.hpp" |
---|---|---|---|
2 | |||
3 | #include "global.hpp" |
||
4 | |||
5 | c76baf23 | Georg Alberding | #include "linefollow2.hpp" |
6 | |||
7 | 58fe0e0b | Thomas Schöpping | using namespace amiro; |
8 | |||
9 | extern Global global;
|
||
10 | |||
11 | 5d138bca | galberding | enum class states{ |
12 | FOLLOW_LINE, |
||
13 | OCCUPY, |
||
14 | RELEASE, |
||
15 | CHARGING |
||
16 | 58fe0e0b | Thomas Schöpping | }; |
17 | |||
18 | d607fcef | galberding | enum msg_content{
|
19 | STOP, |
||
20 | START, |
||
21 | EDGE_LEFT, |
||
22 | EDGE_RIGHT, |
||
23 | FUZZY, |
||
24 | DOCKING |
||
25 | }; |
||
26 | |||
27 | 5d138bca | galberding | // User thread state:
|
28 | states utState = states::FOLLOW_LINE; |
||
29 | 58fe0e0b | Thomas Schöpping | |
30 | // a buffer for the z-value of the accelerometer
|
||
31 | int16_t accel_z; |
||
32 | 5d138bca | galberding | bool running = false; |
33 | 58fe0e0b | Thomas Schöpping | |
34 | int vcnl4020AmbientLight[4] = {0}; |
||
35 | int vcnl4020Proximity[4] = {0}; |
||
36 | |||
37 | c76baf23 | Georg Alberding | |
38 | 58fe0e0b | Thomas Schöpping | // Set the speed by the array
|
39 | void setRpmSpeed(const int (&rpmSpeed)[2]) { |
||
40 | 5d138bca | galberding | global.motorcontrol.setTargetRPM(rpmSpeed[constants::DiWheelDrive::LEFT_WHEEL] * 1000000, rpmSpeed[constants::DiWheelDrive::RIGHT_WHEEL] * 1000000); |
41 | 58fe0e0b | Thomas Schöpping | } |
42 | |||
43 | 5d138bca | galberding | void lightOneLed(Color color, int idx){ |
44 | global.robot.setLightColor(idx, Color(color)); |
||
45 | } |
||
46 | 58fe0e0b | Thomas Schöpping | |
47 | 5d138bca | galberding | void lightAllLeds(Color color){
|
48 | int led = 0; |
||
49 | for(led=0; led<8; led++){ |
||
50 | lightOneLed(color, led); |
||
51 | } |
||
52 | 58fe0e0b | Thomas Schöpping | } |
53 | |||
54 | 9c46b728 | galberding | /**
|
55 | * Get the wanted strategy from the global object.
|
||
56 | */
|
||
57 | LineFollowStrategy determineStrategy(){ |
||
58 | switch(global.lfStrategy){
|
||
59 | case 0: |
||
60 | return LineFollowStrategy::EDGE_RIGHT;
|
||
61 | break;
|
||
62 | case 1: |
||
63 | return LineFollowStrategy::EDGE_LEFT;
|
||
64 | break;
|
||
65 | case 2: |
||
66 | return LineFollowStrategy::FUZZY;
|
||
67 | break;
|
||
68 | case 3: |
||
69 | return LineFollowStrategy::DOCKING;
|
||
70 | default:
|
||
71 | break;
|
||
72 | } |
||
73 | return LineFollowStrategy::NONE;
|
||
74 | } |
||
75 | |||
76 | /**
|
||
77 | * Blocks as long as the position changes.
|
||
78 | */
|
||
79 | void checkForMotion(UserThread *ut){
|
||
80 | int motion = 1; |
||
81 | int led = 0; |
||
82 | types::position oldPos = global.odometry.getPosition(); |
||
83 | while(motion){
|
||
84 | ut->sleep(500);
|
||
85 | types::position tmp = global.odometry.getPosition(); |
||
86 | motion = abs(oldPos.x - tmp.x)+ abs(oldPos.y - tmp.y)+abs(oldPos.z - tmp.z); |
||
87 | oldPos = tmp; |
||
88 | global.robot.setLightColor((led + 1) % 8, Color(Color::YELLOW)); |
||
89 | global.robot.setLightColor(led % 8, Color(Color::BLACK));
|
||
90 | led++; |
||
91 | } |
||
92 | } |
||
93 | |||
94 | |||
95 | /**
|
||
96 | * Turns MotorControl off and checks if position remains stable.
|
||
97 | */
|
||
98 | int checkDockingSuccess(UserThread *ut){
|
||
99 | // global.motorcontrol.setTargetRPM(0,0);
|
||
100 | checkForMotion(ut); |
||
101 | int led = 0; |
||
102 | int success = 0; |
||
103 | global.odometry.resetPosition(); |
||
104 | types::position start = global.startPos = global.odometry.getPosition(); |
||
105 | global.motorcontrol.toggleMotorEnable(); |
||
106 | ut->sleep(1000);
|
||
107 | types::position stop = global.endPos = global.odometry.getPosition(); |
||
108 | global.motorcontrol.toggleMotorEnable(); |
||
109 | // Amiro moved, docking was not successful
|
||
110 | if ((start.x + stop.x) || (start.y + stop.y)){
|
||
111 | for(led=0; led<8; led++){ |
||
112 | global.robot.setLightColor(led, Color(Color::RED)); |
||
113 | } |
||
114 | success = 0;
|
||
115 | }else{
|
||
116 | for(led=0; led<8; led++){ |
||
117 | global.robot.setLightColor(led, Color(Color::GREEN)); |
||
118 | } |
||
119 | success = 1;
|
||
120 | } |
||
121 | |||
122 | ut->sleep(500);
|
||
123 | for(led=0; led<8; led++){ |
||
124 | global.robot.setLightColor(led, Color(Color::BLACK)); |
||
125 | } |
||
126 | return success;
|
||
127 | } |
||
128 | |||
129 | void correctPosition(UserThread *ut, LineFollow &lf, int steps){ |
||
130 | int checkWhite = 0; |
||
131 | int rpmSpeed[2] ={0}; |
||
132 | lf.setStrategy(LineFollowStrategy::EDGE_LEFT); |
||
133 | for (int correction=0; correction<steps; correction++){ |
||
134 | checkWhite = lf.followLine(rpmSpeed); |
||
135 | setRpmSpeed(rpmSpeed); |
||
136 | ut->sleep(CAN::UPDATE_PERIOD); |
||
137 | } |
||
138 | } |
||
139 | 58fe0e0b | Thomas Schöpping | |
140 | |||
141 | UserThread::UserThread() : |
||
142 | chibios_rt::BaseStaticThread<USER_THREAD_STACK_SIZE>() |
||
143 | { |
||
144 | } |
||
145 | |||
146 | UserThread::~UserThread() |
||
147 | { |
||
148 | } |
||
149 | |||
150 | msg_t |
||
151 | UserThread::main() |
||
152 | { |
||
153 | 5d138bca | galberding | /*
|
154 | * SETUP
|
||
155 | */
|
||
156 | 9c46b728 | galberding | int rpmSpeed[2] = {0}; |
157 | int stop[2] = {0}; |
||
158 | int proxyWheelThresh = 18000; |
||
159 | d607fcef | galberding | LineFollowStrategy lStrategy; |
160 | 5d138bca | galberding | for (uint8_t led = 0; led < 8; ++led) { |
161 | global.robot.setLightColor(led, Color(Color::BLACK)); |
||
162 | } |
||
163 | running = false;
|
||
164 | LineFollow lf(&global); |
||
165 | /*
|
||
166 | * LOOP
|
||
167 | */
|
||
168 | while (!this->shouldTerminate()) |
||
169 | { |
||
170 | 58fe0e0b | Thomas Schöpping | /*
|
171 | * read accelerometer z-value
|
||
172 | */
|
||
173 | accel_z = global.lis331dlh.getAccelerationForce(LIS331DLH::AXIS_Z); |
||
174 | |||
175 | /*
|
||
176 | * evaluate the accelerometer
|
||
177 | */
|
||
178 | c76baf23 | Georg Alberding | |
179 | 5d138bca | galberding | //Features over can: (Line Following)
|
180 | //SetKP
|
||
181 | //SetKI
|
||
182 | //SetKd ?
|
||
183 | //SetSleepTime
|
||
184 | //SeForwardSpeed? or SetMaxSpeed
|
||
185 | //DriveOnLeftLine
|
||
186 | //DriveOnRightLine
|
||
187 | |||
188 | //if accel_z<-900
|
||
189 | //send can event (one time)
|
||
190 | // Line following is started if amiro roteted
|
||
191 | if (accel_z < -900 /*-0.9g*/) { //new: (can.allowLineFollowOnTurn && accel_z < 900) || can.startLineFollow optional feature |
||
192 | // set the front LEDs to blue for one second
|
||
193 | lightAllLeds(Color::GREEN); |
||
194 | this->sleep(1000); |
||
195 | lightAllLeds(Color::BLACK); |
||
196 | running = !running; |
||
197 | d607fcef | galberding | // If message was received handle it here:
|
198 | } else if(global.msgReceived){ |
||
199 | |||
200 | global.msgReceived = false;
|
||
201 | running = true;
|
||
202 | switch(global.lfStrategy){
|
||
203 | case msg_content::START:
|
||
204 | break;
|
||
205 | case msg_content::STOP:
|
||
206 | running = false;
|
||
207 | break;
|
||
208 | case msg_content::EDGE_RIGHT:
|
||
209 | lStrategy = LineFollowStrategy::EDGE_RIGHT; |
||
210 | break;
|
||
211 | case msg_content::EDGE_LEFT:
|
||
212 | lStrategy = LineFollowStrategy::EDGE_LEFT; |
||
213 | break;
|
||
214 | case msg_content::FUZZY:
|
||
215 | lStrategy = LineFollowStrategy::FUZZY; |
||
216 | break;
|
||
217 | case msg_content::DOCKING:
|
||
218 | utState = states::OCCUPY; |
||
219 | lStrategy = LineFollowStrategy::EDGE_RIGHT; |
||
220 | break;
|
||
221 | default:
|
||
222 | break;
|
||
223 | } |
||
224 | |||
225 | 5d138bca | galberding | } |
226 | d607fcef | galberding | |
227 | 5d138bca | galberding | if(running){
|
228 | 9c46b728 | galberding | switch(utState){
|
229 | case states::FOLLOW_LINE:{
|
||
230 | d607fcef | galberding | // LineFollowStrategy lStrategy = determineStrategy();
|
231 | 9c46b728 | galberding | if(lStrategy == LineFollowStrategy::DOCKING){
|
232 | utState = states::OCCUPY; |
||
233 | break;
|
||
234 | } |
||
235 | lf.setStrategy(lStrategy); |
||
236 | lf.followLine(rpmSpeed); |
||
237 | setRpmSpeed(rpmSpeed); |
||
238 | break;
|
||
239 | } |
||
240 | case states::OCCUPY:{
|
||
241 | // Get Wheel proxy sensors
|
||
242 | int WL = global.vcnl4020[constants::DiWheelDrive::PROX_WHEEL_LEFT].getProximityScaledWoOffset();
|
||
243 | int WR = global.vcnl4020[constants::DiWheelDrive::PROX_WHEEL_LEFT].getProximityScaledWoOffset();
|
||
244 | // Check for black
|
||
245 | if ((WL+WR) < proxyWheelThresh){ /*TODO: Only check for one sensor */ |
||
246 | global.motorcontrol.setTargetRPM(0,0); |
||
247 | 5d138bca | galberding | |
248 | 9c46b728 | galberding | // Stop when in docking state and take further actions
|
249 | if(lf.getStrategy() == LineFollowStrategy::DOCKING){
|
||
250 | if(checkDockingSuccess(this)){ |
||
251 | utState = states::CHARGING; |
||
252 | break;
|
||
253 | }else{
|
||
254 | correctPosition(this, lf, 250); |
||
255 | lf.setStrategy(LineFollowStrategy::DOCKING); |
||
256 | // break;
|
||
257 | } |
||
258 | }else{
|
||
259 | checkForMotion(this);
|
||
260 | // 180° Rotation
|
||
261 | global.distcontrol.setTargetPosition(0, 3141592, 10000); |
||
262 | // BaseThread::sleep(8000);
|
||
263 | checkForMotion(this);
|
||
264 | correctPosition(this, lf, 250); |
||
265 | // break;
|
||
266 | lf.setStrategy(LineFollowStrategy::DOCKING); |
||
267 | |||
268 | } |
||
269 | } |
||
270 | |||
271 | // Set correct following
|
||
272 | d607fcef | galberding | // lf.setStrategy(LineFollowStrategy::EDGE_RIGHT);
|
273 | 9c46b728 | galberding | lf.followLine(rpmSpeed); |
274 | setRpmSpeed(rpmSpeed); |
||
275 | |||
276 | break;
|
||
277 | } |
||
278 | case states::RELEASE:{
|
||
279 | break;
|
||
280 | } |
||
281 | case states::CHARGING:{
|
||
282 | d607fcef | galberding | setRpmSpeed(stop); |
283 | 9c46b728 | galberding | break;
|
284 | } |
||
285 | default:{
|
||
286 | break;
|
||
287 | } |
||
288 | } |
||
289 | |||
290 | }else{
|
||
291 | // Stop
|
||
292 | setRpmSpeed(stop); |
||
293 | } |
||
294 | 58fe0e0b | Thomas Schöpping | |
295 | 5d138bca | galberding | this->sleep(CAN::UPDATE_PERIOD);
|
296 | } |
||
297 | 58fe0e0b | Thomas Schöpping | |
298 | return RDY_OK;
|
||
299 | } |