Finished padcontroller bearing reading; Debugged direct control of motor speeds
Benjamin Bardin
11 years ago
2 | 2 | <classpathentry excluding="org/haldean/chopper/pilot/nav/NavListTest.java|org/haldean/chopper/pilot/nav/NavVelTest.java|org/haldean/chopper/server/|org/haldean/blob/JavaImage.java|org/haldean/blob/SegmentTest.java" including="org/haldean/blob/|org/haldean/chopper/nav/|org/haldean/chopper/pilot/" kind="src" path="src"/> |
3 | 3 | <classpathentry kind="src" path="gen"/> |
4 | 4 | <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> |
5 | <classpathentry kind="lib" path="/home/haldean/Git/droidcopter/jars/amarino.jar"/> | |
5 | <classpathentry kind="lib" path="/home/benjamin/workspace/droidcopter/jars/amarino.jar"/> | |
6 | 6 | <classpathentry kind="output" path="bin"/> |
7 | 7 | </classpath> |
21 | 21 | |
22 | 22 | public static void setMotorSpeeds(double m1, double m2, double m3, double m4) { |
23 | 23 | Amarino.sendDataToArduino(context, BT_DEVICE_ADDR, 'A', (int) (100 * m1)); |
24 | Amarino.sendDataToArduino(context, BT_DEVICE_ADDR, 'B', (int) (100 * m2)); | |
25 | Amarino.sendDataToArduino(context, BT_DEVICE_ADDR, 'C', (int) (100 * m3)); | |
24 | Amarino.sendDataToArduino(context, BT_DEVICE_ADDR, 'C', (int) (100 * m2)); | |
25 | Amarino.sendDataToArduino(context, BT_DEVICE_ADDR, 'B', (int) (100 * m3)); | |
26 | 26 | Amarino.sendDataToArduino(context, BT_DEVICE_ADDR, 'D', (int) (100 * m4)); |
27 | 27 | } |
28 | 28 | }⏎ |
86 | 86 | comm.registerReceiver(NAV, nav); |
87 | 87 | comm.registerReceiver(CSYS, nav); |
88 | 88 | comm.registerReceiver(GUID, guid); |
89 | comm.registerReceiver(GUID, nav); | |
89 | 90 | |
90 | 91 | nav.registerReceiver(comm); |
91 | 92 | nav.registerReceiver(guid); |
57 | 57 | /** Handles messages for the thread */ |
58 | 58 | private Handler mHandler; |
59 | 59 | |
60 | /** Stores whether or not a motor-eval loop should add itself to the queue again. **/ | |
61 | private boolean mReviseMotorSpeeds = true; | |
62 | ||
60 | 63 | /** Stores orientation data persistently, as expected values in case lock is not immediately available*/ |
61 | 64 | private double mAzimuth; |
62 | 65 | private double mPitchDeg; |
132 | 135 | //Temporary: need real tuning values at some point. Crap. |
133 | 136 | for (int i = 0; i < 3; i++) |
134 | 137 | for (int j = 0; j < 3; j++) |
135 | mGain[i][j] = .05; | |
138 | mGain[i][j] = .005; | |
136 | 139 | for (int j = 0; j < 3; j++) { |
137 | 140 | mGain[3][j] = .0005; |
138 | 141 | } |
156 | 159 | public void handleMessage(Message msg) { |
157 | 160 | switch (msg.what) { |
158 | 161 | case EVAL_MOTOR_SPEED: |
162 | Log.d(TAG, "evaluating motor speed"); | |
159 | 163 | reviseMotorSpeed(); |
160 | 164 | //Log.d(TAG, getErrorString()); |
161 | 165 | updateReceivers(getErrorString()); |
187 | 191 | } |
188 | 192 | } |
189 | 193 | }; |
190 | mHandler.sendEmptyMessage(EVAL_MOTOR_SPEED); | |
194 | //mHandler.sendEmptyMessage(EVAL_MOTOR_SPEED); | |
195 | receiveMessage("GUID:VECTOR:0:0:0:0", null); | |
191 | 196 | Looper.loop(); |
192 | 197 | } |
193 | 198 | |
197 | 202 | * @param source The source of the message, if a reply is needed. May be null. |
198 | 203 | */ |
199 | 204 | public void receiveMessage(String msg, Receivable source) { |
200 | Log.d(TAG, "Receiving message " + msg); | |
205 | //Log.d(TAG, "Receiving message " + msg); | |
201 | 206 | String[] parts = msg.split(":"); |
202 | 207 | if (parts[0].equals("GUID")) { |
203 | 208 | if (parts[1].equals("PID")) { |
216 | 221 | } |
217 | 222 | if (parts[1].equals("AUTOMATIC")) { |
218 | 223 | mHandler.removeMessages(NEW_GUID_VECTOR); |
224 | mReviseMotorSpeeds = true; | |
219 | 225 | if (!mHandler.hasMessages(EVAL_MOTOR_SPEED)) |
220 | 226 | mHandler.sendEmptyMessage(EVAL_MOTOR_SPEED); |
221 | 227 | } |
228 | 234 | mAbsVec = true; |
229 | 235 | } |
230 | 236 | if (parts[1].equals("VECTOR")) { |
237 | mReviseMotorSpeeds = false; | |
231 | 238 | mHandler.removeMessages(EVAL_MOTOR_SPEED); |
232 | 239 | Double[] myVector = new Double[4]; |
233 | 240 | for (int i = 0; i < 4; i++) { |
413 | 420 | case 3: //Azimuth |
414 | 421 | break; |
415 | 422 | } |
416 | ||
417 | 423 | mTorques[i] = dmotor; |
418 | 424 | //Log.v(TAG, "Torque " + i + " " + dmotor); |
419 | 425 | } |
471 | 477 | //Log.v(TAG, "motors: " + mMotorSpeed[0] + ", " + mMotorSpeed[1] + ", " + mMotorSpeed[2] + ", " + mMotorSpeed[3]); |
472 | 478 | //Sleep a while |
473 | 479 | long timetonext = (1000 / PIDREPS) - (System.currentTimeMillis() - starttime); |
474 | if (timetonext > 0) | |
475 | mHandler.sendEmptyMessageDelayed(EVAL_MOTOR_SPEED, timetonext); | |
476 | else | |
477 | mHandler.sendEmptyMessage(EVAL_MOTOR_SPEED); | |
480 | if (mReviseMotorSpeeds) { | |
481 | if (timetonext > 0) | |
482 | mHandler.sendEmptyMessageDelayed(EVAL_MOTOR_SPEED, timetonext); | |
483 | else | |
484 | mHandler.sendEmptyMessage(EVAL_MOTOR_SPEED); | |
485 | } | |
478 | 486 | } |
479 | 487 | |
480 | 488 | /* To be finished */ |
178 | 178 | setTask(BASIC_AUTO, taskList); |
179 | 179 | setTask(NO_CONN, "{ VEL!No_Conn!0!0!-1!0!1000000!-1!-5 -6}"); |
180 | 180 | setTask(LOW_POWER, "{ VEL!Low_Power!0!0!-1!0!1000000!-1!-7 -8}"); |
181 | ||
182 | mNavStatus.set(BASIC_AUTO); | |
183 | autoPilot(true); | |
181 | //mNavStatus.set(BASIC_AUTO); | |
182 | ||
183 | ||
184 | //autoPilot(true); | |
184 | 185 | |
185 | 186 | Looper.loop(); |
186 | 187 | } |
261 | 262 | public void receiveMessage(String msg, Receivable source) { |
262 | 263 | Log.d(TAG, "Receiving " + msg); |
263 | 264 | String[] parts = msg.split(":"); |
265 | if (parts[0].equals("GUID")) { | |
266 | if (parts[1].equals("VECTOR")) { | |
267 | autoPilot(false); | |
268 | } | |
269 | } | |
264 | 270 | if (parts[0].equals("NAV")) { |
265 | 271 | if (parts[1].equals("SET")) { |
266 | 272 | Log.v(TAG, "Updating Nav Status"); |
102 | 102 | for (int i=0; i<4; i++) { |
103 | 103 | taskString += ":" + speeds[i]; |
104 | 104 | } |
105 | DataReceiver.sendToDefault(navGoToManual); | |
105 | //DataReceiver.sendToDefault(navGoToManual); | |
106 | 106 | DataReceiver.sendToDefault(taskString); |
107 | 107 | } |
108 | 108 |
40 | 40 | |
41 | 41 | private int lastButtonMask = 0; |
42 | 42 | |
43 | private boolean globeMovement = false; | |
43 | private boolean globeMovement = true; | |
44 | 44 | |
45 | 45 | private final double minDiff = 250; //ms |
46 | 46 | private long lastAxesUpdate; |
47 | ||
48 | private double theta = 0; //bearing | |
47 | 49 | |
48 | 50 | /** Create a new PadController |
49 | 51 | * @param _ui The ServerHost to act upon */ |
155 | 157 | public boolean buttonIsSet(int button) { |
156 | 158 | return buttonIsSet(lastButtonMask, button); |
157 | 159 | } |
160 | ||
161 | /** Perform an action based on the status of the buttons | |
162 | * | |
163 | */ | |
164 | private void buttonMaybeAction() { | |
165 | int currentMask = buttonMask(); | |
166 | /* In Conrol Mode, B changes orientation */ | |
167 | if (!globeMovement && buttonIsSet(currentMask, BUTTON_B)) { | |
168 | double mX = getAxis(AXIS_L_H); | |
169 | double mY = -getAxis(AXIS_L_V); | |
170 | if ( Math.sqrt(mX * mX + mY * mY) > .7 ) { //only take measurements .7 radius out. Arbitrary. Magic Number. Deal. | |
171 | double angle = Math.atan2(mY, mX); | |
172 | angle = angle * 180.0 / Math.PI; | |
173 | angle = 90.0 - angle; | |
174 | if (angle < 0.0) | |
175 | angle += 360.0; | |
176 | theta = angle; | |
177 | } | |
178 | } | |
179 | } | |
158 | 180 | |
159 | 181 | /** Perform an action based on the status of the buttons |
160 | 182 | * @param mask The mask representings buttons that have changed state */ |
196 | 218 | sl.setGlobeMode(globeMovement); |
197 | 219 | Debug.log("Globe control is now " + ((globeMovement) ? "on" : "off")); |
198 | 220 | } |
199 | ||
221 | ||
200 | 222 | /* In Globe Mode, B activates or disactivates follow mode */ |
201 | 223 | if (globeMovement && buttonIsSet(mask, BUTTON_B)) |
202 | 224 | ui.globeComponent.toggleFollow(); |
203 | 225 | } |
204 | ||
226 | ||
227 | ||
205 | 228 | /** Get the value of a joystick axis, filtering out noisy results |
206 | 229 | * @param axis The index of the axis to check |
207 | 230 | * @return A number from -1 to 1 representing the value of the joystick */ |
218 | 241 | } |
219 | 242 | |
220 | 243 | /** Trigger events based on the values of the axes */ |
221 | private void axesAction() { | |
244 | private void axesAction(int mask) { | |
222 | 245 | if (globeMovement) { |
223 | 246 | float zoom = getAxis(AXIS_L_TRIGGER) - getAxis(AXIS_R_TRIGGER); |
224 | 247 | ui.globeComponent.moveView(getAxis(AXIS_L_H), getAxis(AXIS_L_V), |
225 | 248 | zoom, getAxis(AXIS_R_V), getAxis(AXIS_R_H)); |
226 | 249 | } else { |
227 | 250 | double[] vels = new double[3]; |
228 | vels[0] = getAxis(AXIS_L_H); | |
229 | vels[1] = -getAxis(AXIS_L_V); | |
230 | vels[2] = getAxis(AXIS_R_V); | |
251 | ||
252 | if (!buttonIsSet(mask, BUTTON_B)) { //if it's set, we're taking bearing. don't alter velocity. | |
253 | vels[0] = getAxis(AXIS_L_H); | |
254 | vels[1] = -getAxis(AXIS_L_V); | |
255 | vels[2] = getAxis(AXIS_R_V); | |
256 | ||
231 | 257 | |
232 | boolean updateVec = false; | |
233 | if (System.currentTimeMillis() - lastAxesUpdate > minDiff) { | |
234 | updateVec = true; | |
235 | } | |
236 | ||
237 | if (updateVec) { | |
238 | lastAxesUpdate = System.currentTimeMillis(); | |
239 | //3.0 is the value of the maximum normal vector | |
240 | double adjustment = EnsignCrusher.MAX_VELOCITY / Math.sqrt(3.0); | |
241 | for (double v : vels) { | |
242 | v *= adjustment; | |
243 | } | |
244 | ||
245 | EnsignCrusher.manualVelocity(vels); | |
258 | boolean updateVec = false; | |
259 | if (System.currentTimeMillis() - lastAxesUpdate > minDiff) { | |
260 | updateVec = true; | |
261 | } | |
262 | ||
263 | if (updateVec) { | |
264 | lastAxesUpdate = System.currentTimeMillis(); | |
265 | //3.0 is the value of the maximum normal vector | |
266 | double adjustment = EnsignCrusher.MAX_VELOCITY / Math.sqrt(3.0); | |
267 | for (double v : vels) { | |
268 | v *= adjustment; | |
269 | } | |
270 | ||
271 | EnsignCrusher.manualVelocity(vels, theta); | |
272 | } | |
246 | 273 | } |
247 | 274 | } |
248 | 275 | } |
258 | 285 | lastButtonMask = mask; |
259 | 286 | |
260 | 287 | if (enabled) { |
261 | axesAction(); | |
288 | axesAction(mask); | |
262 | 289 | if (newButtons != 0) { |
263 | 290 | buttonAction(newButtons); |
264 | 291 | } |
292 | buttonMaybeAction(); | |
265 | 293 | } |
266 | 294 | |
267 | 295 | try { |