DreamForce 2013 Mini-Hack Challenge Project
Dependencies: ADXL345 USBDevice filter mbed
Fork of df-minihack-slingshot by
Revision 0:a2c33a8eded1, committed 2013-10-30
- Comitter:
- ansond
- Date:
- Wed Oct 30 19:07:09 2013 +0000
- Child:
- 1:d9d593d4ea39
- Commit message:
- initial check-in
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ADXL345.lib Wed Oct 30 19:07:09 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/aberk/code/ADXL345/#bd8f0f20f433
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice.lib Wed Oct 30 19:07:09 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/USBDevice/#d495202c90f4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Wed Oct 30 19:07:09 2013 +0000
@@ -0,0 +1,169 @@
+/* mbed USB Slingshot,
+ *
+ * Copyright (c) 2010-2011 mbed.org, MIT License
+ *
+ * smokrani, sford, danson, sgrove
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "mbed.h"
+#include "USBMouse.h"
+#include "ADXL345.h"
+
+// Physical interfaces
+USBMouse mouse;
+ADXL345 accelerometer(p5, p6, p7, p8);
+AnalogIn stretch_sensor(p15);
+BusOut leds(LED1, LED2, LED3, LED4);
+
+//
+// DreamForce 2013 Challenge:
+// - Adjust the resultant slingshot angle for the difference between the accelerometer angle and the relative angle of the sling to the slingshot body.
+// - Result should be in radians: up > 0 > down just like with get_angle() below - except adjusted!
+// - Note: You may need to add some filters to optimize (and stabilize) the readings from the potentiometers
+//
+float adjust_for_sling_angle(float slingshot_body_angle) {
+ float modified_angle = slingshot_body_angle; // default
+
+ // innovate!!!
+
+ // return the modified angle taking into account the sling angle relative to the slingshot body
+ return modified_angle;
+}
+
+// Return slingshot angle in radians, up > 0 > down
+float get_angle() {
+ int readings[3];
+ accelerometer.getOutput(readings);
+ float x = (int16_t)readings[0];
+ float z = (int16_t)readings[2];
+ return atan(z / x);
+}
+
+// Return normalised stretch value based on bounds of all readings seen
+float get_stretch() {
+ static float min_strength = 0.7;
+ static float max_strength = 0.7;
+ float current_strength = stretch_sensor.read();
+ if(current_strength > max_strength) { max_strength = current_strength; }
+ if(current_strength < min_strength) { min_strength = current_strength; }
+ float stretch = (current_strength - min_strength) / (max_strength - min_strength);
+ return 1.0 - stretch;
+}
+
+// move mouse to a location relative to the start point, stepping as needed
+void move_mouse(int x, int y) {
+ const int STEP = 10;
+ static int current_x = 0;
+ static int current_y = 0;
+
+ int move_x = x - current_x;
+ int move_y = y - current_y;
+
+ // Move the mouse, in steps of max step size to ensure it is picked up by OS
+ while(move_x > STEP) { mouse.move(STEP, 0); move_x -= STEP; }
+ while(move_x < -STEP) { mouse.move(-STEP, 0); move_x += STEP; }
+ while(move_y > STEP) { mouse.move(0, STEP); move_y -= STEP; }
+ while(move_y < -STEP) { mouse.move(0, -STEP); move_y += STEP; }
+ mouse.move(move_x, move_y);
+
+ current_x = x;
+ current_y = y;
+}
+
+template <class T>
+T filter(T* array, int len, T value) {
+ T mean = 0.0;
+ for(int i = 0; i<len - 1; i++) {
+ mean += array[i + 1];
+ array[i] = array[i + 1];
+ }
+ mean += value;
+ array[len - 1] = value;
+ return mean / (T)len;
+}
+
+typedef enum {
+ WAITING = 2,
+ AIMING = 4,
+ FIRING = 8
+} state_t;
+
+int main() {
+ leds = 1;
+
+ // setup accelerometer
+ accelerometer.setPowerControl(0x00);
+ accelerometer.setDataFormatControl(0x0B);
+ accelerometer.setDataRate(ADXL345_3200HZ);
+ accelerometer.setPowerControl(0x08);
+
+ state_t state = WAITING;
+ Timer timer;
+
+ float angles[8] = {0};
+ float stretches[8] = {0};
+
+ while(1) {
+
+ // get the slingshot parameters
+ float this_stretch = get_stretch();
+ float this_angle = get_angle();
+
+ // apply some filtering
+ float stretch = filter(stretches, 8, this_stretch);
+ float angle = filter(angles, 8, this_angle);
+
+ // DreamForce 2013 Challenge: Adjust the angle to account for the relative angle between the sling and the slingshot body
+ angle = adjust_for_sling_angle(angle);
+
+ leds = state;
+
+ // act based on the current state
+ switch (state) {
+ case WAITING:
+ if(stretch > 0.5) { // significant stretch, considered starting
+ mouse.press(MOUSE_LEFT);
+ state = AIMING;
+ }
+ break;
+
+ case AIMING:
+ if(stretch - this_stretch > 0.1) { // rapid de-stretch, considered a fire
+ mouse.release(MOUSE_LEFT);
+ move_mouse(0, 0);
+ timer.start();
+ state = FIRING;
+ } else {
+ int x = 0.0 - cos(angle) * stretch * 200;
+ int y = sin(angle) * stretch * 200;
+ move_mouse(x, y);
+ }
+ break;
+
+ case FIRING:
+ if(timer > 3.0) {
+ timer.stop();
+ timer.reset();
+ state = WAITING;
+ }
+ break;
+ };
+
+ wait(0.01);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Oct 30 19:07:09 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/a9913a65894f \ No newline at end of file
