├── .gitignore ├── Buggy ├── Buggy.ino ├── Gait2.h ├── Geometry.h ├── Leg.h ├── Mark1Config.h ├── Mark2Config.h ├── SimpleMovements.h └── SmoothFloat.h ├── BuggyRemote ├── .classpath ├── .project ├── .settings │ ├── org.eclipse.jdt.core.prefs │ └── org.eclipse.jdt.ui.prefs ├── AndroidManifest.xml ├── gen │ └── com │ │ └── poconoco │ │ └── buggyremote │ │ ├── BuildConfig.java │ │ └── R.java ├── ic_launcher-web.png ├── libs │ └── android-support-v4.jar ├── proguard-project.txt ├── project.properties ├── res │ ├── drawable-hdpi │ │ └── ic_launcher.png │ ├── drawable-ldpi │ │ └── ic_launcher.png │ ├── drawable-mdpi │ │ └── ic_launcher.png │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ ├── layout │ │ └── activity_main.xml │ ├── menu │ │ └── activity_main.xml │ ├── values-v11 │ │ └── styles.xml │ ├── values-v14 │ │ └── styles.xml │ └── values │ │ ├── strings.xml │ │ └── styles.xml └── src │ └── com │ └── poconoco │ └── buggyremote │ ├── BuggyBluetooth.java │ ├── BuggyBodyMovement.java │ ├── BuggyBodyShift.java │ ├── BuggyMandibles.java │ ├── BuggyProtocol.java │ ├── BuggySensors.java │ └── MainActivity.java ├── README.md └── serial_interface.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # Compiled Dynamic libraries 7 | *.so 8 | 9 | # Compiled Static libraries 10 | *.lai 11 | *.la 12 | *.a 13 | -------------------------------------------------------------------------------- /Buggy/Buggy.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "Leg.h" 4 | #include "Gait2.h" 5 | #include "Mark2Config.h" 6 | #include "SimpleMovements.h" 7 | 8 | static Point zero(0,0,0); 9 | 10 | static const int N = 6; 11 | static Leg legs[N]; 12 | static Leg mandibles[2]; 13 | 14 | static SimpleMovements moveSimple(legs, N, mandibles, 2); 15 | static Gait2 gait(legs); 16 | 17 | static bool attached = false; 18 | static bool mandiblesAttached = false; 19 | 20 | char command = 0; 21 | unsigned long lastCommandTime = 0; 22 | static float progress = 0; 23 | 24 | SmoothFloat fpitch(0,0); 25 | SmoothFloat froll(0,0); 26 | SmoothFloat fyaw(0,0); 27 | SmoothFloat fbodyX(0,0); 28 | SmoothFloat fbodyY(0,0); 29 | SmoothFloat fbodyZ(0,0); 30 | 31 | SmoothFloat fRMandibleX(0,0); 32 | SmoothFloat fRMandibleY(0,0); 33 | SmoothFloat fRMandibleZ(0,0); 34 | SmoothFloat fLMandibleX(0,0); 35 | SmoothFloat fLMandibleY(0,0); 36 | SmoothFloat fLMandibleZ(0,0); 37 | 38 | void attachAllLegs() 39 | { 40 | if (attached) 41 | return; 42 | 43 | attached = true; 44 | 45 | for (int i = 0; i < N; i++) 46 | legs[i].attach(); 47 | } 48 | 49 | void detachAllLegs() 50 | { 51 | if (! attached) 52 | return; 53 | 54 | attached = false; 55 | 56 | for (int i = 0; i < N; i++) 57 | legs[i].detach(); 58 | } 59 | 60 | void attachMandibles() 61 | { 62 | if (mandiblesAttached) 63 | return; 64 | 65 | mandiblesAttached = true; 66 | mandibles[0].attach(); 67 | mandibles[1].attach(); 68 | } 69 | 70 | void detachMandibles() 71 | { 72 | if (! mandiblesAttached) 73 | return; 74 | 75 | mandiblesAttached = false; 76 | mandibles[0].detach(); 77 | mandibles[1].detach(); 78 | } 79 | 80 | bool toggleMandibles() 81 | { 82 | mandiblesAttached ? detachMandibles() 83 | : attachMandibles(); 84 | 85 | return mandiblesAttached; 86 | } 87 | 88 | bool toggleLegs() 89 | { 90 | attached ? detachAllLegs() 91 | : attachAllLegs(); 92 | 93 | return attached; 94 | } 95 | 96 | bool tryMultibyte(char cmd) 97 | { 98 | static unsigned long lastMoveCommandTime = 0; 99 | const unsigned long now = millis(); 100 | 101 | if (cmd == 'b') 102 | { 103 | while (Serial1.available() < 7) 104 | tickMovements(); 105 | 106 | char x, y, z, pitch, roll, yaw; 107 | x = Serial1.read(); 108 | y = Serial1.read(); 109 | z = Serial1.read(); 110 | pitch = Serial1.read(); 111 | roll = Serial1.read(); 112 | yaw = Serial1.read(); 113 | 114 | // Confirm footer byte 115 | if (Serial1.read() != 'B') 116 | return false; 117 | 118 | fbodyX.setTarget(normalizeByte(x, 40)); 119 | fbodyY.setTarget(normalizeByte(y, 40)); 120 | fbodyZ.setTarget(normalizeByte(z, 40)); 121 | fpitch.setTarget(normalizeByte(pitch, PI / 6)); 122 | froll.setTarget(normalizeByte(roll, PI / 6)); 123 | fyaw.setTarget(normalizeByte(yaw, PI / 6)); 124 | 125 | return true; 126 | } 127 | 128 | if (cmd == 'm') 129 | { 130 | while (Serial1.available() < 5) 131 | tickMovements(); 132 | 133 | char x,y,turn, speed; 134 | 135 | x = Serial1.read(); 136 | y = Serial1.read(); 137 | turn = Serial1.read(); 138 | speed = Serial1.read(); 139 | 140 | // Confirm footer byte 141 | if (Serial1.read() != 'M') 142 | return false; 143 | 144 | gait.setStep(Point(normalizeByte(x, 40), 145 | normalizeByte(y, 40), 146 | 0), 147 | turn != 0, 148 | normalizeByte(turn, 1.0)); 149 | 150 | if (speed < 0) 151 | speed = 0; 152 | 153 | gait.setSpeed(normalizeByte(speed, 2.0)); 154 | 155 | return true; 156 | } 157 | 158 | if (cmd == 'g') 159 | { 160 | while (Serial1.available() < 2) 161 | tickMovements(); 162 | 163 | char gaitId = Serial1.read(); 164 | 165 | // Confirm footer byte 166 | if (Serial1.read() != 'G') 167 | return false; 168 | 169 | switch (gaitId) 170 | { 171 | case 1: 172 | gait.setGait2x3(); 173 | break; 174 | case 2: 175 | gait.setGait6x1(); 176 | break; 177 | case 3: 178 | gait.setGait3x2(); 179 | break; 180 | } 181 | 182 | lastMoveCommandTime = now; 183 | return true; 184 | } 185 | 186 | if (cmd == 'p') 187 | { 188 | while (Serial1.available() < 7) 189 | tickMovements(); 190 | 191 | char buffer[6]; 192 | for (int i = 0; i < sizeof(buffer); ++i) 193 | buffer[i] = Serial1.read(); 194 | 195 | // Confirm footer byte 196 | if (Serial1.read() != 'P') 197 | return false; 198 | 199 | fRMandibleX.setTarget(normalizeByte(buffer[0], 50)); 200 | fRMandibleY.setTarget(normalizeByte(buffer[1], 50)); 201 | fRMandibleZ.setTarget(normalizeByte(buffer[2], 50)); 202 | 203 | fLMandibleX.setTarget(normalizeByte(buffer[3], 50)); 204 | fLMandibleY.setTarget(normalizeByte(buffer[4], 50)); 205 | fLMandibleZ.setTarget(normalizeByte(buffer[5], 50)); 206 | 207 | return true; 208 | } 209 | 210 | if (now - lastMoveCommandTime > 1000) 211 | { 212 | gait.setSpeed(0); 213 | gait.setStep(zero, false, 0); 214 | 215 | lastMoveCommandTime = now + 1000000; 216 | } 217 | 218 | return false; 219 | } 220 | 221 | void tickMovements() 222 | { 223 | gait.tick(); 224 | 225 | #ifdef SMOOTH_ANGLES 226 | for (int i = 0; i < N; i++) 227 | legs[i].tick(); 228 | #endif 229 | 230 | static unsigned long _lastTickTime = 0; 231 | const unsigned long now = millis(); 232 | const unsigned long deltaT = now - _lastTickTime; 233 | const float angleStepDelta = ((PI * 0.25) * 0.001) * (float) deltaT; 234 | const float shiftStepDelta = (100.0 * 0.001) * (float) deltaT; 235 | const float shiftMandibleDelta = (200.0 * 0.001) * (float) deltaT; 236 | 237 | Point bodyShift(fbodyX.getCurrent(shiftStepDelta), 238 | fbodyY.getCurrent(shiftStepDelta), 239 | fbodyZ.getCurrent(shiftStepDelta)); 240 | 241 | moveSimple.shiftAbsolute( 242 | bodyShift, 243 | fpitch.getCurrent(angleStepDelta), 244 | froll.getCurrent(angleStepDelta), 245 | fyaw.getCurrent(angleStepDelta)); 246 | 247 | moveSimple.mandiblesReach(Point(fRMandibleX.getCurrent(shiftMandibleDelta), 248 | fRMandibleY.getCurrent(shiftMandibleDelta), 249 | fRMandibleZ.getCurrent(shiftMandibleDelta)), 250 | Point(fLMandibleX.getCurrent(shiftMandibleDelta), 251 | fLMandibleY.getCurrent(shiftMandibleDelta), 252 | fLMandibleZ.getCurrent(shiftMandibleDelta))); 253 | 254 | _lastTickTime = now; 255 | } 256 | 257 | void setup() 258 | { 259 | Serial1.begin(9600); 260 | // Serial1.println("AT+BAUD8"); 261 | // delay(500); 262 | // Serial1.begin(115200); 263 | 264 | LegConfiguration::apply(legs, N); 265 | MandibleConfiguration::apply(mandibles, 2); 266 | 267 | moveSimple.rememberDefault(); 268 | 269 | for (Leg* leg = legs; leg < legs + N; leg++) 270 | leg->reachRelativeToDefault(zero); 271 | 272 | for (Leg* mandible = mandibles; mandible < mandibles + 2; mandible++) 273 | mandible->reachRelativeToDefault(zero); 274 | 275 | gait.setGait3x2(); 276 | } 277 | 278 | void loop() 279 | { 280 | tickMovements(); 281 | char incoming; 282 | 283 | if (Serial1.available() > 0) 284 | incoming = Serial1.read(); 285 | else 286 | return; 287 | 288 | if (tryMultibyte(incoming)) 289 | return; 290 | 291 | // One shot actions 292 | if (incoming == ' ') 293 | toggleLegs(); 294 | else if (incoming == '_') 295 | toggleMandibles(); 296 | } 297 | -------------------------------------------------------------------------------- /Buggy/Gait2.h: -------------------------------------------------------------------------------- 1 | #ifndef GAIT_2_H__ 2 | #define GAIT_2_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "Leg.h" 8 | #include "Geometry.h" 9 | #include "SmoothFloat.h" 10 | 11 | class LegCycle 12 | { 13 | public: 14 | 15 | LegCycle() 16 | : _leg(NULL) 17 | , _cycleShift(0) 18 | , _stepHeight(0) 19 | , _turn(false) 20 | , _turnAngle(0) 21 | , _turnCX(0) 22 | , _turnCY(0) 23 | { 24 | setCycleMiddle(127); 25 | } 26 | 27 | void setLeg(Leg *leg, bool rightLeg) 28 | { 29 | _leg = leg; 30 | _rightLeg = rightLeg; 31 | } 32 | 33 | void setCycleShift(byte shift) 34 | { 35 | _cycleShift = shift; 36 | } 37 | 38 | void setCycleMiddle(byte middle) 39 | { 40 | _cycleMiddle = middle; 41 | _invCycleMiddle = 1.0 / static_cast(_cycleMiddle); 42 | 43 | _cycleAfterMiddle = 255 - _cycleMiddle; 44 | _invCycleAfterMiddle = 1.0 / static_cast(_cycleAfterMiddle); 45 | } 46 | 47 | void setStep(Point start, 48 | Point stop, 49 | float height, 50 | bool turn, 51 | float turnAngle, 52 | float turnCX, 53 | float turnCY) 54 | { 55 | _start = start; 56 | _stop = stop; 57 | _stepHeight = height; 58 | _turn = turn; 59 | _turnAngle = turnAngle; 60 | _turnCX = turnCX; 61 | _turnCY = turnCY; 62 | } 63 | 64 | void setCyclePos(byte pos) 65 | { 66 | float norm1pos; 67 | float height; 68 | cycle(shiftCyclePos(pos), norm1pos, height); 69 | 70 | Point point; 71 | 72 | if (! _turn) 73 | { 74 | point.x = _start.x + (_stop.x - _start.x) * norm1pos; 75 | point.y = _start.y + (_stop.y - _start.y) * norm1pos; 76 | point.z = _start.z + (_stop.z - _start.z) * norm1pos + height; 77 | 78 | _leg->reachRelativeToDefault(point); 79 | } 80 | else 81 | { 82 | point = _start; 83 | point.z += height; 84 | _leg->reachRelativeToDefaultAndRotate(point, _turnAngle * norm1pos, _turnCX, _turnCY); 85 | } 86 | } 87 | 88 | private: 89 | 90 | inline byte shiftCyclePos(byte pos) 91 | { 92 | // Hope overflow will work as expected here :) 93 | return pos + _cycleShift; 94 | } 95 | 96 | void cycle(byte cyclePos, float& norm1pos, float& height) 97 | { 98 | if (cyclePos <= _cycleMiddle) 99 | { 100 | norm1pos = static_cast(cyclePos) * _invCycleMiddle; 101 | height = 0.0; 102 | } 103 | else 104 | { 105 | norm1pos = static_cast(_cycleAfterMiddle - (cyclePos - _cycleMiddle)) * _invCycleAfterMiddle; 106 | height = _stepHeight * (1 - fabs(0.5 - norm1pos) * 2); 107 | } 108 | } 109 | 110 | private: 111 | 112 | Leg* _leg; 113 | byte _cycleShift; 114 | byte _cycleMiddle; 115 | float _invCycleMiddle; 116 | byte _cycleAfterMiddle; 117 | float _invCycleAfterMiddle; 118 | 119 | Point _start; 120 | Point _stop; 121 | float _stepHeight; 122 | bool _turn; 123 | float _turnAngle; 124 | float _turnCX; 125 | float _turnCY; 126 | bool _rightLeg; 127 | }; 128 | 129 | class Gait2 130 | { 131 | public: 132 | 133 | Gait2(Leg* legs) 134 | : _legs(legs) 135 | , _stepHeight(50) 136 | , _stepPerSecond(0, 0) 137 | , _lastTickTime(0) 138 | , _currentCyclePos(0) 139 | , _turn(0, 0) 140 | , _directionX(0, 0) 141 | , _directionY(0, 0) 142 | , _directionZ(0, 0) 143 | , _doTurn(false) 144 | { 145 | for (byte i = 0; i < 6; ++i) 146 | _legCycles[i].setLeg(&_legs[i], i < 3); 147 | 148 | _rightLegCycles = _legCycles; 149 | _leftLegCycles = _legCycles + 3; 150 | } 151 | 152 | void setGait2x3() 153 | { 154 | _legCycles[0].setCycleShift(0); 155 | _legCycles[1].setCycleShift(127); 156 | _legCycles[2].setCycleShift(0); 157 | _legCycles[3].setCycleShift(127); 158 | _legCycles[4].setCycleShift(0); 159 | _legCycles[5].setCycleShift(127); 160 | 161 | for (byte i = 0; i < 6; ++i) 162 | _legCycles[i].setCycleMiddle(127); 163 | } 164 | 165 | void setGait3x2() 166 | { 167 | _legCycles[0].setCycleShift(0); 168 | _legCycles[5].setCycleShift(0); 169 | 170 | _legCycles[1].setCycleShift((255 / 3) * 1); 171 | _legCycles[4].setCycleShift((255 / 3) * 1); 172 | 173 | _legCycles[2].setCycleShift((255 / 3) * 2); 174 | _legCycles[3].setCycleShift((255 / 3) * 2); 175 | 176 | for (byte i = 0; i < 6; ++i) 177 | _legCycles[i].setCycleMiddle(255 - (255 / 3)); 178 | } 179 | 180 | void setGait6x1() 181 | { 182 | _legCycles[0].setCycleShift(0); 183 | _legCycles[1].setCycleShift((255 / 6) * 1); 184 | _legCycles[2].setCycleShift((255 / 6) * 2); 185 | _legCycles[3].setCycleShift((255 / 6) * 3); 186 | _legCycles[4].setCycleShift((255 / 6) * 4); 187 | _legCycles[5].setCycleShift((255 / 6) * 5); 188 | 189 | for (byte i = 0; i < 6; ++i) 190 | _legCycles[i].setCycleMiddle(255 - (255 / 6)); 191 | } 192 | 193 | void setStep(Point dir, bool turn, float turnValue) 194 | { 195 | _directionX.setTarget(dir.x); 196 | _directionY.setTarget(dir.y); 197 | _directionZ.setTarget(dir.z); 198 | _turn.setTarget(turnValue); 199 | _doTurn = turn; 200 | } 201 | 202 | void tickStep() 203 | { 204 | Point direction(_directionX.getCurrent(), 205 | _directionY.getCurrent(), 206 | _directionZ.getCurrent()); 207 | 208 | float cx, cy; // rotate around these points 209 | float angle; 210 | if (_doTurn) 211 | { 212 | angle = _turn.getCurrent() * 0.7; 213 | 214 | cx = distanceToHorde(fabs(direction.y), angle); 215 | cy = 0; 216 | 217 | if (direction.y < 0) 218 | angle *= -1; 219 | } 220 | 221 | Point stepStart = direction * 0.5; 222 | Point stepStop = stepStart * (-1); 223 | 224 | for (byte i = 0; i < 6; ++i) 225 | _legCycles[i].setStep(stepStart, 226 | stepStop, 227 | _stepHeight, 228 | _doTurn, 229 | angle, 230 | cx, 231 | cy); 232 | } 233 | 234 | void setSpeed(float stepsPerSecond) 235 | { 236 | _stepPerSecond.setTarget(stepsPerSecond); 237 | } 238 | 239 | void tick() 240 | { 241 | const unsigned long now = millis(); 242 | const unsigned long deltaT = now - _lastTickTime; 243 | _lastTickTime = now; 244 | 245 | const float speedStepDelta = 0.01 * (float) deltaT; 246 | const float directionStepDelta = 0.1 * (float) deltaT; 247 | const float turnStepDelta = 0.01 * (float) deltaT; 248 | _directionX.getCurrent(directionStepDelta); 249 | _directionY.getCurrent(directionStepDelta); 250 | _directionZ.getCurrent(directionStepDelta); 251 | _turn.getCurrent(turnStepDelta); 252 | 253 | tickStep(); 254 | 255 | const float cycleDelta = deltaT * (255.0 * 0.001) * _stepPerSecond.getCurrent(speedStepDelta); 256 | _currentCyclePos += cycleDelta; 257 | 258 | while (_currentCyclePos >= 255) 259 | _currentCyclePos -= 255; 260 | 261 | byte currCyclePosByte = (byte) _currentCyclePos; 262 | 263 | for (byte i = 0; i < 6; ++i) 264 | _legCycles[i].setCyclePos(currCyclePosByte); 265 | } 266 | 267 | private: 268 | 269 | LegCycle _legCycles[6]; 270 | LegCycle* _rightLegCycles; 271 | LegCycle* _leftLegCycles; 272 | Leg* _legs; 273 | float _stepHeight; 274 | float _currentCyclePos; // 0 .. 255 number to be rounded to byte 275 | 276 | bool _doTurn; 277 | SmoothFloat _stepPerSecond; 278 | SmoothFloat _turn; 279 | SmoothFloat _directionX; 280 | SmoothFloat _directionY; 281 | SmoothFloat _directionZ; 282 | 283 | unsigned long _lastTickTime; 284 | }; 285 | 286 | #endif 287 | -------------------------------------------------------------------------------- /Buggy/Geometry.h: -------------------------------------------------------------------------------- 1 | #ifndef GEOMETRY_H__ 2 | #define GEOMETRY_H__ 3 | 4 | #include 5 | 6 | #define sqr(x) ((x)*(x)) 7 | #define PI 3.141592653589793238 8 | #define rad2deg(x) ( (180.0 / PI) * (x) ) 9 | #define deg2rad(x) ( (PI / 180.0) * (x) ) 10 | #define fabs(x) ((x) >= 0 ? (x) : - (x)) 11 | #define max(x, y) ((x) > (y) ? (x) : (y)) 12 | #define distanceSqr2D(x1, y1, x2, y2) (sqr((x1) - (x2)) + sqr((y1) - (y2))) 13 | #define distance2D(x1, y1, x2, y2) (sqrt(distanceSqr2D(x1, y1, x2, y2))) 14 | 15 | // TODO: Rename third quarter fix to something more meaningful 16 | float polarAngle(float x, float y, bool thirdQuarterFix) 17 | { 18 | if (x > 0) 19 | { 20 | if (thirdQuarterFix && y > 0) 21 | return atan(y / x) - 2 * PI; 22 | return atan(y / x); 23 | } 24 | 25 | if (x < 0 && y >= 0) 26 | { 27 | if (thirdQuarterFix) 28 | return atan(y / x) - PI; 29 | return atan(y / x) + PI; 30 | } 31 | 32 | if (x < 0 && y < 0) 33 | return atan(y / x) - PI; 34 | 35 | // x = 0 36 | if (y > 0) 37 | return PI * 0.5; 38 | 39 | if (y < 0) 40 | return PI * -0.5; 41 | 42 | // y = 0 43 | return 0; 44 | } 45 | 46 | struct Point 47 | { 48 | Point() 49 | {} 50 | 51 | Point(float _x, float _y, float _z) 52 | { 53 | x = _x; 54 | y = _y; 55 | z = _z; 56 | } 57 | 58 | float x, y, z; 59 | 60 | Point operator+(Point& that) 61 | { 62 | return Point(x + that.x, 63 | y + that.y, 64 | z + that.z); 65 | } 66 | 67 | Point operator-(Point& that) 68 | { 69 | return Point(x - that.x, 70 | y - that.y, 71 | z - that.z); 72 | } 73 | 74 | Point operator*(float m) 75 | { 76 | return Point(x * m, 77 | y * m, 78 | z * m); 79 | } 80 | 81 | Point operator/(float d) 82 | { 83 | return Point(x / d, 84 | y / d, 85 | z / d); 86 | } 87 | 88 | void operator=(Point& that) 89 | { 90 | x = that.x; 91 | y = that.y; 92 | z = that.z; 93 | } 94 | 95 | // Workaround for an gccavr issue with reference args 96 | void assign(Point that) 97 | { 98 | x = that.x; 99 | y = that.y; 100 | z = that.z; 101 | } 102 | 103 | void assign(float _x, float _y, float _z) 104 | { 105 | x = _x; 106 | y = _y; 107 | z = _z; 108 | } 109 | 110 | void assignZero() 111 | { 112 | x = y = z = 0; 113 | } 114 | 115 | float maxDistance(Point& that) 116 | { 117 | float dx = fabs(x - that.x); 118 | float dy = fabs(y - that.y); 119 | float dz = fabs(z - that.z); 120 | 121 | return max(dz, max(dx, dy)); 122 | } 123 | 124 | float distance(Point& that) 125 | { 126 | return sqrt(sqr(x - that.x) + sqr(y - that.y) + sqr(z - that.z)); 127 | } 128 | 129 | }; 130 | 131 | void normalize2D(Point& vector, float normalizer) 132 | { 133 | vector.x = vector.x * normalizer; 134 | vector.y = vector.y * normalizer; 135 | // vector.z = vector.z * normalizer; 136 | } 137 | 138 | bool floatEqual(float a, float b) 139 | { 140 | return fabs(a - b) < 0.00001; 141 | } 142 | 143 | float normalizeByte(char b, float normal) 144 | { 145 | return ((float) b) * normal * 0.0078125; // * (1 / 128.0); 146 | } 147 | 148 | float distanceToHorde(float hordeLength, 149 | float hordeAngle) 150 | { 151 | return (hordeLength * 0.5) / tan(hordeAngle * 0.5); 152 | } 153 | 154 | void rotate2d(float cx, float cy, float angle, Point& p) 155 | { 156 | float s = sin(angle); 157 | float c = cos(angle); 158 | 159 | // translate point back to origin: 160 | p.x -= cx; 161 | p.y -= cy; 162 | 163 | // rotate point 164 | float xnew = p.x * c - p.y * s; 165 | float ynew = p.x * s + p.y * c; 166 | 167 | // translate point back: 168 | p.x = xnew + cx; 169 | p.y = ynew + cy; 170 | } 171 | 172 | #endif 173 | -------------------------------------------------------------------------------- /Buggy/Leg.h: -------------------------------------------------------------------------------- 1 | #ifndef LEG_H__ 2 | #define LEG_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "Geometry.h" 8 | #include "SmoothFloat.h" 9 | 10 | #define DONT_MOVE 123456.123456 11 | 12 | class Leg 13 | { 14 | public: 15 | 16 | Leg() 17 | : _debug(false) 18 | , _attached(false) 19 | , _cServoRestAngle(PI / 2) 20 | , _fServoRestAngle(PI / 2) 21 | , _tServoRestAngle(PI / 2) 22 | , _cServoDirection(0.0) 23 | , _fServoDirection(0.0) 24 | , _tServoDirection(0.0) 25 | , _delayReach(false) 26 | , _cAngle(_cServoRestAngle, _cServoRestAngle) 27 | , _fAngle(_fServoRestAngle, _fServoRestAngle) 28 | , _tAngle(_tServoRestAngle, _tServoRestAngle) 29 | , _lastTickTime(0) 30 | , _speedRadMsec((PI * 2) / 1000) 31 | {} 32 | 33 | void debug(bool on) 34 | { 35 | _debug = on; 36 | } 37 | 38 | void setPins(int coxaPin, int femurPin, int tibiaPin) 39 | { 40 | if (_debug) 41 | return; 42 | 43 | _coxaPin = coxaPin; 44 | _femurPin = femurPin; 45 | _tibiaPin = tibiaPin; 46 | } 47 | 48 | void attach() 49 | { 50 | if (_attached) 51 | return; 52 | 53 | _attached = true; 54 | _cServo.attach(_coxaPin); 55 | _fServo.attach(_femurPin); 56 | _tServo.attach(_tibiaPin); 57 | } 58 | 59 | void detach() 60 | { 61 | if (! _attached) 62 | return; 63 | 64 | _attached = false; 65 | _cServo.detach(); 66 | _fServo.detach(); 67 | _tServo.detach(); 68 | } 69 | 70 | void configureCoxa(float cStartX, 71 | float cStartY, 72 | float cStartAngle, 73 | float cFemurOffset) 74 | { 75 | _cStart.x = cStartX; 76 | _cStart.y = cStartY; 77 | _cStartAngle = cStartAngle; 78 | _cFemurOffset = cFemurOffset; 79 | } 80 | 81 | void configureFemur(float fStartZOffset, 82 | float fStartFarOffset, 83 | float fLength, 84 | float fStartAngle) 85 | { 86 | _fStartZOffset = fStartZOffset; 87 | _fStartFarOffset = fStartFarOffset; 88 | _fLength = fLength; 89 | _fStartAngle = fStartAngle; 90 | } 91 | 92 | void configureTibia(float tLenght, 93 | float tStartAngle) 94 | { 95 | _tLenght = tLenght; 96 | _tStartAngle = tStartAngle; 97 | } 98 | 99 | void configureServoDirections(float cServoDirection, 100 | float fServoDirection, 101 | float tServoDirection, 102 | bool thirdQuarterFix) 103 | { 104 | _cServoDirection = cServoDirection; 105 | _fServoDirection = fServoDirection; 106 | _tServoDirection = tServoDirection; 107 | _thirdQuarterFix = thirdQuarterFix; 108 | } 109 | 110 | void tuneRestAngles(float cServoRestAngle, 111 | float fServoRestAngle, 112 | float tServoRestAngle) 113 | { 114 | _cServoRestAngle = cServoRestAngle; 115 | _fServoRestAngle = fServoRestAngle; 116 | _tServoRestAngle = tServoRestAngle; 117 | } 118 | 119 | bool reset() 120 | { 121 | move(0, 0, 0); 122 | } 123 | 124 | // Can't use reference argument here due to limitations in gcc avr 125 | void configureDefault(Point def, bool move) 126 | { 127 | _defaultPos = def; 128 | _currentPos = def; 129 | 130 | if (move) 131 | reach(def); 132 | } 133 | 134 | void shiftDefault(Point def) 135 | { 136 | Point delta = def - _defaultPos; 137 | _currentPos.assign(_currentPos + delta); 138 | _defaultPos = def; 139 | 140 | reach(_currentPos); 141 | } 142 | 143 | void shiftDefaultRelative(Point& delta) 144 | { 145 | _currentPos.assign(_currentPos + delta); 146 | _defaultPos.assign(_defaultPos + delta); 147 | 148 | reach(_currentPos); 149 | } 150 | 151 | void reachRelativeToDefault(Point& dest) 152 | { 153 | _currentPos.assign(_defaultPos + dest); 154 | reach(_currentPos); 155 | } 156 | 157 | void reachRelativeToDefaultAndRotate(Point& dest, float angle, float cx, float cy) 158 | { 159 | _currentPos.assign(_defaultPos + dest); 160 | rotate2d(cx, cy, angle, _currentPos); 161 | reach(_currentPos); 162 | } 163 | 164 | void reachRelativeToCurrent(Point& dest) 165 | { 166 | _currentPos.assign(_currentPos + dest); 167 | reach(_currentPos); 168 | } 169 | 170 | void reachAbsolute(Point& dest) 171 | { 172 | _currentPos = dest; 173 | reach(_currentPos); 174 | } 175 | 176 | Point getCurrentRelative() 177 | { 178 | return _currentPos - _defaultPos; 179 | } 180 | 181 | Point& getCurrentPos() 182 | { 183 | return _currentPos; 184 | } 185 | 186 | Point& getDefaultPos() 187 | { 188 | return _defaultPos; 189 | } 190 | 191 | void rememberRaisePoint() 192 | { 193 | _raisePoint.assign(getCurrentRelative()); 194 | } 195 | 196 | Point& getRaisePoint() 197 | { 198 | return _raisePoint; 199 | } 200 | 201 | void delayReach() 202 | { 203 | _delayReach = true; 204 | } 205 | 206 | void commitDelayedReach() 207 | { 208 | _delayReach = false; 209 | reach(_delayedReach); 210 | } 211 | 212 | void tick() 213 | { 214 | #ifdef SMOOTH_ANGLES 215 | const unsigned long now = millis(); 216 | const unsigned long deltaT = now - _lastTickTime; 217 | 218 | _lastTickTime = now; 219 | 220 | const float stepDelta = _speedRadMsec * deltaT; 221 | 222 | moveInternal(_cAngle.getCurrent(stepDelta), 223 | _fAngle.getCurrent(stepDelta), 224 | _tAngle.getCurrent(stepDelta)); 225 | #endif 226 | } 227 | 228 | private: 229 | 230 | void reach(Point& dest) 231 | { 232 | if (_delayReach) 233 | { 234 | _delayedReach = dest; 235 | return; 236 | } 237 | 238 | float hDist = sqrt( sqr(dest.x - _cStart.x) + sqr(dest.y - _cStart.y) ); 239 | float additionalCoxaAngle = hDist == 0.0 ? DONT_MOVE 240 | : asin( _cFemurOffset / hDist ); 241 | 242 | float primaryCoxaAngle = polarAngle(dest.x - _cStart.x, dest.y - _cStart.y, _thirdQuarterFix); 243 | 244 | float cAngle = hDist == 0.0 ? DONT_MOVE 245 | : primaryCoxaAngle - additionalCoxaAngle - _cStartAngle; 246 | 247 | // Moving to local Coxa-Femur-target coordinate system 248 | // Note the case when hDist <= _cFemurOffset. This is for the blind zone. 249 | // We never can't reach the point that is nearer to the _cStart then 250 | // femur offset (_fStartFarOffset) 251 | float localDestX = hDist <= _cFemurOffset 252 | ? - _fStartFarOffset 253 | : sqrt(sqr(hDist) - sqr(_cFemurOffset)) - _fStartFarOffset; 254 | 255 | float localDestY = dest.z - _fStartZOffset; 256 | 257 | // Check reachability 258 | float localDistSqr = sqr(localDestX) + sqr(localDestY); 259 | if (localDistSqr > sqr(_fLength + _tLenght)) 260 | { 261 | // log("Can't reach!"); 262 | return; 263 | } 264 | 265 | // Find joint as circle intersect ( equations from http://e-maxx.ru/algo/circles_intersection & http://e-maxx.ru/algo/circle_line_intersection ) 266 | float A = -2 * localDestX; 267 | float B = -2 * localDestY; 268 | float C = sqr(localDestX) + sqr(localDestY) + sqr(_fLength) - sqr(_tLenght); 269 | float X0 = -A * C / (sqr(A) + sqr(B)); 270 | float Y0 = -B * C / (sqr(A) + sqr(B)); 271 | float D = sqrt( sqr(_fLength) - (sqr(C) / (sqr(A) + sqr(B))) ); 272 | float mult = sqrt ( sqr(D) / (sqr(A) + sqr(B))); 273 | float ax, ay, bx, by; 274 | ax = X0 + B * mult; 275 | bx = X0 - B * mult; 276 | ay = Y0 - A * mult; 277 | by = Y0 + A * mult; 278 | 279 | // Select solution on top as joint 280 | float jointLocalX = ax; 281 | float jointLocalY = ay; 282 | 283 | float primaryFemurAngle = polarAngle(jointLocalX, jointLocalY, false); 284 | float fAngle = primaryFemurAngle - _fStartAngle; 285 | 286 | float primaryTibiaAngle = polarAngle(localDestX - jointLocalX, localDestY - jointLocalY, false); 287 | float tAngle = (primaryTibiaAngle - fAngle) - _tStartAngle; 288 | 289 | move(cAngle, fAngle, tAngle); 290 | } 291 | 292 | void move(float cAngle, float fAngle, float tAngle) 293 | { 294 | #ifdef SMOOTH_ANGLES 295 | _cAngle.setTarget(cAngle); 296 | _fAngle.setTarget(fAngle); 297 | _tAngle.setTarget(tAngle); 298 | 299 | tick(); 300 | #else 301 | moveInternal(cAngle, fAngle, tAngle); 302 | #endif 303 | } 304 | 305 | void moveInternal(float cAngle, float fAngle, float tAngle) 306 | { 307 | if (! _attached) 308 | return; 309 | 310 | int mc = rad2deg(_cServoDirection * cAngle + _cServoRestAngle); 311 | int mf = rad2deg(_fServoDirection * fAngle + _fServoRestAngle); 312 | int mt = rad2deg(_tServoDirection * tAngle + _tServoRestAngle); 313 | 314 | if (! _debug) 315 | { 316 | if (cAngle != DONT_MOVE) 317 | _cServo.write(coxaLimit(mc)); 318 | if (fAngle != DONT_MOVE) 319 | _fServo.write(femurLimit(mf)); 320 | if (tAngle != DONT_MOVE) 321 | _tServo.write(tibiaLimit(mt)); 322 | } 323 | else 324 | { 325 | // log("Angles:"); 326 | // log(mc); 327 | // log(mf); 328 | // log(mt); 329 | } 330 | } 331 | 332 | int coxaLimit(int x) 333 | { 334 | const int cMin = 90 - 70; 335 | const int cMax = 90 + 70; 336 | 337 | if (x < cMin) return cMin; 338 | if (x > cMax) return cMax; 339 | 340 | return x; 341 | } 342 | 343 | int femurLimit(int x) 344 | { 345 | const int fMin = 90 - 70; 346 | const int fMax = 90 + 70; 347 | 348 | if (x < fMin) return fMin; 349 | if (x > fMax) return fMax; 350 | 351 | return x; 352 | } 353 | 354 | int tibiaLimit(int x) 355 | { 356 | const int tMin = 90 - 70; 357 | const int tMax = 90 + 70; 358 | 359 | if (x < tMin) return tMin; 360 | if (x > tMax) return tMax; 361 | 362 | return x; 363 | } 364 | 365 | private: 366 | bool _debug; 367 | 368 | // 3dof leg has Coxa, Femur and Tibia segments and joints. 369 | // Coxa is nearest to the body, Tibia is farthest. 370 | 371 | // Config 372 | Point _cStart; // Coordinates of the Coxa start point 373 | float _cStartAngle; // Angle where Coxa is pointed to when relaxed 374 | float _cFemurOffset; // Offset of Femur and Tibia axis from the Coxa axis 375 | float _fStartZOffset; // Botton offset of Femur start from the z0 plane 376 | float _fStartFarOffset; 377 | float _fLength; // Femur length 378 | float _fStartAngle; 379 | float _tLenght; // Tibia length 380 | float _tStartAngle; 381 | 382 | // Servo rest angles are for fine tune of angles. By default it is pi/2 383 | float _cServoRestAngle; 384 | float _fServoRestAngle; 385 | float _tServoRestAngle; 386 | 387 | // Servo direction should be 1.0 or -1.0 - determines servo orientation 388 | float _cServoDirection; 389 | float _fServoDirection; 390 | float _tServoDirection; 391 | 392 | Point _raisePoint; 393 | Point _defaultPos; 394 | Point _currentPos; 395 | bool _attached; 396 | bool _thirdQuarterFix; 397 | 398 | int _coxaPin; 399 | int _femurPin; 400 | int _tibiaPin; 401 | 402 | // Delayed move 403 | bool _delayReach; 404 | Point _delayedReach; 405 | 406 | // Arduino servos 407 | Servo _cServo; 408 | Servo _fServo; 409 | Servo _tServo; 410 | 411 | // Smooth angle movement 412 | unsigned long _lastTickTime; 413 | SmoothFloat _cAngle; 414 | SmoothFloat _fAngle; 415 | SmoothFloat _tAngle; 416 | float _speedRadMsec; 417 | 418 | }; 419 | 420 | typedef Leg* PLeg; 421 | 422 | #endif 423 | -------------------------------------------------------------------------------- /Buggy/Mark1Config.h: -------------------------------------------------------------------------------- 1 | #ifndef MARK1_CONFIG_H__ 2 | #define MARK1_CONFIG_H__ 3 | 4 | class LegConfiguration 5 | { 6 | public: 7 | 8 | // NOTE: legs are attached after calling this method but are not moved 9 | static void apply(Leg* legs, int N) 10 | { 11 | Leg* rightLegs = legs; 12 | Leg* leftLegs = legs + N / 2; 13 | 14 | rightLegs[0].setPins(46, 47, 39); 15 | rightLegs[1].setPins(40, 41, 42); 16 | rightLegs[2].setPins(43, 44, 45); 17 | 18 | leftLegs[0].setPins(29, 28, 36); 19 | leftLegs[1].setPins(35, 34, 33); 20 | leftLegs[2].setPins(32, 31, 30); 21 | 22 | rightLegs[0].configureServoDirections(-1, -1, 1, false); 23 | leftLegs [0].configureServoDirections(-1, 1, -1, true); 24 | 25 | rightLegs[1].configureServoDirections(-1, -1, 1, false); 26 | leftLegs [1].configureServoDirections(-1, 1, -1, true); 27 | 28 | rightLegs[2].configureServoDirections(-1, -1, 1, false); 29 | leftLegs [2].configureServoDirections(-1, 1, -1, true); 30 | 31 | for (int i = 0; i < 3; i++) 32 | { 33 | rightLegs[i].configureFemur(-26, 12, 46.5, deg2rad(10)); 34 | leftLegs [i].configureFemur(-26, 12, 46.5, deg2rad(10)); 35 | 36 | rightLegs[i].configureTibia(58, deg2rad(-70)); 37 | leftLegs [i].configureTibia(58, deg2rad(-70)); 38 | } 39 | 40 | rightLegs[0].configureCoxa( 34, 65, deg2rad( 20), 10); 41 | leftLegs [0].configureCoxa(-34, 65, deg2rad(- (180 + 20)), -10); 42 | 43 | rightLegs[1].configureCoxa( 52, 0, deg2rad(- 20), 10); 44 | leftLegs [1].configureCoxa(-52, 0, deg2rad(- (180 - 20)), -10); 45 | 46 | rightLegs[2].configureCoxa( 34, -65, deg2rad(- 63), 10); 47 | leftLegs [2].configureCoxa(-34, -65, deg2rad(- (180 - 63)), -10); 48 | 49 | rightLegs[0].configureDefault(Point( 60, 130, -70), true); 50 | leftLegs [0].configureDefault(Point(-60, 130, -70), true); 51 | 52 | rightLegs[1].configureDefault(Point( 110, -10, -65), true); 53 | leftLegs [1].configureDefault(Point(-110, -10, -70), true); 54 | 55 | rightLegs[2].configureDefault(Point( 70, -120, -70), true); 56 | leftLegs [2].configureDefault(Point(-70, -120, -70), true); 57 | 58 | // Fine tuning 59 | rightLegs[0].tuneRestAngles(PI / 2, 60 | PI / 2 + deg2rad(10), 61 | PI / 2); 62 | 63 | leftLegs[0].tuneRestAngles(PI / 2, 64 | PI / 2 - deg2rad(5), 65 | PI / 2); 66 | 67 | leftLegs[1].tuneRestAngles(PI / 2, 68 | PI / 2, 69 | PI / 2 - deg2rad(10)); 70 | 71 | rightLegs[1].tuneRestAngles(PI / 2, 72 | PI / 2, 73 | PI / 2 + deg2rad(20)); 74 | 75 | 76 | leftLegs[2].tuneRestAngles(PI / 2, 77 | PI / 2 - deg2rad(10), 78 | PI / 2); 79 | 80 | } 81 | 82 | }; 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /Buggy/Mark2Config.h: -------------------------------------------------------------------------------- 1 | #ifndef MARK1_CONFIG_H__ 2 | #define MARK1_CONFIG_H__ 3 | 4 | class MandibleConfiguration 5 | { 6 | public: 7 | 8 | static void apply(Leg* mandibles, int N) 9 | { 10 | if (N != 2) // Only 2 mandibles supported for now 11 | return; 12 | 13 | Leg* rightMandible = mandibles; 14 | Leg* leftMandible = mandibles + 1; 15 | 16 | rightMandible->setPins(50, 49, 48); 17 | leftMandible ->setPins(25, 26, 27); 18 | 19 | rightMandible->configureServoDirections(-1, -1, 1, false); 20 | leftMandible ->configureServoDirections(-1, 1, -1, true); 21 | 22 | /* configureFemur(float fStartZOffset, 23 | * float fStartFarOffset, 24 | * float fLength, 25 | * float fStartAngle) 26 | */ 27 | rightMandible->configureFemur(-26, 12, 46.5, deg2rad(10)); 28 | leftMandible ->configureFemur(-26, 12, 46.5, deg2rad(10)); 29 | 30 | /* configureTibia(float tLenght, 31 | * float tStartAngle) 32 | */ 33 | rightMandible->configureTibia(58, deg2rad(-70)); 34 | leftMandible ->configureTibia(58, deg2rad(-70)); 35 | 36 | /* 37 | * configureCoxa(float cStartX, 38 | * float cStartY, 39 | * float cStartAngle, 40 | * float cFemurOffset) 41 | */ 42 | rightMandible->configureCoxa( 30, -20, deg2rad( 70), 10); 43 | leftMandible ->configureCoxa(-30, -20, deg2rad(- (180 + 70)), -10); 44 | 45 | rightMandible->configureDefault(Point( 30, 0, -70), true); 46 | leftMandible ->configureDefault(Point(-30, 0, -70), true); 47 | } 48 | }; 49 | 50 | class LegConfiguration 51 | { 52 | public: 53 | 54 | // NOTE: legs are attached after calling this method but are not moved 55 | static void apply(Leg* legs, int N) 56 | { 57 | Leg* rightLegs = legs; 58 | Leg* leftLegs = legs + N / 2; 59 | 60 | rightLegs[0].setPins(46, 47, 39); 61 | rightLegs[1].setPins(40, 41, 42); 62 | rightLegs[2].setPins(43, 44, 45); 63 | 64 | leftLegs[0].setPins(29, 28, 36); 65 | leftLegs[1].setPins(35, 34, 33); 66 | leftLegs[2].setPins(32, 31, 30); 67 | 68 | /* 69 | * configureServoDirections(float cServoDirection, 70 | * float fServoDirection, 71 | * float tServoDirection, 72 | * bool thirdQuarterFix) 73 | */ 74 | 75 | rightLegs[0].configureServoDirections(1, -1, 1, false); 76 | leftLegs [0].configureServoDirections(1, 1, -1, true); 77 | 78 | rightLegs[1].configureServoDirections(1, -1, 1, false); 79 | leftLegs [1].configureServoDirections(1, 1, -1, true); 80 | 81 | rightLegs[2].configureServoDirections(1, -1, 1, false); 82 | leftLegs [2].configureServoDirections(1, 1, -1, true); 83 | 84 | for (int i = 0; i < 3; i++) 85 | { 86 | /* configureFemur(float fStartZOffset, 87 | * float fStartFarOffset, 88 | * float fLength, 89 | * float fStartAngle) 90 | */ 91 | rightLegs[i].configureFemur(-26, 3, 32, deg2rad(0)); 92 | leftLegs [i].configureFemur(-26, 3, 32, deg2rad(0)); 93 | 94 | /* configureTibia(float tLenght, 95 | * float tStartAngle) 96 | */ 97 | rightLegs[i].configureTibia(61, deg2rad(-90)); 98 | leftLegs [i].configureTibia(61, deg2rad(-90)); 99 | } 100 | 101 | /* 102 | * configureCoxa(float cStartX, 103 | * float cStartY, 104 | * float cStartAngle, 105 | * float cFemurOffset) 106 | */ 107 | rightLegs[0].configureCoxa( 23, 55, deg2rad( 54), 5); 108 | leftLegs [0].configureCoxa(-23, 55, deg2rad(- (180 + 54)), -5); 109 | 110 | rightLegs[1].configureCoxa( 28, 2, deg2rad(- 0), 5); 111 | leftLegs [1].configureCoxa(-28, 3, deg2rad(- (180 - 0)), -5); 112 | 113 | rightLegs[2].configureCoxa( 24, -38, deg2rad(- 34), 5); 114 | leftLegs [2].configureCoxa(-24, -38, deg2rad(- (180 - 34)), -5); 115 | 116 | /* 117 | * configureDefault(Point def, bool move) 118 | */ 119 | rightLegs[0].configureDefault(Point( 45, 90, -90), true); 120 | leftLegs [0].configureDefault(Point(-45, 90, -90), true); 121 | 122 | rightLegs[1].configureDefault(Point( 70, 10, -90), true); 123 | leftLegs [1].configureDefault(Point(-70, 10, -90), true); 124 | 125 | rightLegs[2].configureDefault(Point( 60, -60, -90), true); 126 | leftLegs [2].configureDefault(Point(-60, -60, -90), true); 127 | 128 | /* 129 | * tuneRestAngles(float cServoRestAngle, 130 | * float fServoRestAngle, 131 | * float tServoRestAngle) 132 | * +/- deg2rad(10) 133 | */ 134 | rightLegs[0].tuneRestAngles(PI / 2, 135 | PI / 2 - deg2rad(5), 136 | PI / 2); 137 | 138 | leftLegs[0].tuneRestAngles(PI / 2, 139 | PI / 2 + deg2rad(10), 140 | PI / 2); 141 | 142 | rightLegs[1].tuneRestAngles(PI / 2, 143 | PI / 2, 144 | PI / 2); 145 | 146 | leftLegs[1].tuneRestAngles(PI / 2, 147 | PI / 2 - deg2rad(5), 148 | PI / 2 - deg2rad(5)); 149 | 150 | rightLegs[2].tuneRestAngles(PI / 2, 151 | PI / 2 + deg2rad(10), 152 | PI / 2); 153 | 154 | leftLegs[2].tuneRestAngles(PI / 2, 155 | PI / 2 + deg2rad(5), 156 | PI / 2); 157 | 158 | } 159 | 160 | }; 161 | 162 | #endif 163 | -------------------------------------------------------------------------------- /Buggy/SimpleMovements.h: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLE_MOVEMENTS_H__ 2 | #define SIMPLE_MOVEMENTS_H__ 3 | 4 | class SimpleMovements 5 | { 6 | public: 7 | SimpleMovements(Leg* legs, int legCount, Leg* mandibles, int mandibleCount) 8 | : _legs(legs) 9 | , _legCount(legCount) 10 | , _mandibles(mandibles) 11 | , _mandibleCount(mandibleCount) 12 | { 13 | //_defaultPositions = new Point[_legCount]; 14 | //_defaultMandiblePositions = new Point[_mandibleCount]; 15 | 16 | _speedFactor = 0.025; 17 | } 18 | 19 | ~SimpleMovements() 20 | { 21 | ..delete _defaultPositions; 22 | //delete _defaultMandiblePositions; 23 | } 24 | 25 | void rememberDefault() 26 | { 27 | for (byte i = 0; i < _legCount; ++i) 28 | _defaultPositions[i] = _legs[i].getDefaultPos(); 29 | 30 | for (byte i = 0; i < _mandibleCount; ++i) 31 | _defaultMandiblePositions[i] = _mandibles[i].getDefaultPos(); 32 | 33 | _linearShift.assignZero(); 34 | } 35 | 36 | void shiftAbsolute(Point& absolute, float pitch, float roll, float yaw) 37 | { 38 | for (byte i = 0; i < _legCount; ++i) 39 | _legs[i].delayReach(); 40 | 41 | for (byte i = 0; i < _legCount; ++i) 42 | _legs[i].shiftDefault(_defaultPositions[i] + absolute); 43 | 44 | shiftPitch(pitch); 45 | shiftRoll(roll); 46 | shiftYaw(yaw); 47 | 48 | for (byte i = 0; i < _legCount; ++i) 49 | _legs[i].commitDelayedReach(); 50 | } 51 | 52 | void mandiblesReach(Point right, Point left) 53 | { 54 | _mandibles[0].shiftDefault(_defaultMandiblePositions[0] + right); 55 | _mandibles[1].shiftDefault(_defaultMandiblePositions[1] + left); 56 | } 57 | 58 | void shift(Point& delta) 59 | { 60 | for (byte i = 0; i < _legCount; ++i) 61 | _legs[i].shiftDefaultRelative(delta); 62 | 63 | // TODO: Do we need to store shift in _linearShift? 64 | } 65 | 66 | void shiftPitch(float angleDelta) 67 | { 68 | float sinval = sin(angleDelta); 69 | float cosval = cos(angleDelta); 70 | 71 | for (byte i = 0; i < _legCount; ++i) 72 | { 73 | Point currDef = _legs[i].getDefaultPos(); 74 | Point newDef; 75 | newDef.x = currDef.x; 76 | newDef.y = currDef.y * cosval - currDef.z * sinval; 77 | newDef.z = currDef.y * sinval + currDef.z * cosval; 78 | 79 | _legs[i].shiftDefault(newDef); 80 | } 81 | } 82 | 83 | void shiftRoll(float angleDelta) 84 | { 85 | float sinval = sin(angleDelta); 86 | float cosval = cos(angleDelta); 87 | 88 | for (byte i = 0; i < _legCount; ++i) 89 | { 90 | Point currDef = _legs[i].getDefaultPos(); 91 | Point newDef; 92 | newDef.x = currDef.x * cosval - currDef.z * sinval; 93 | newDef.y = currDef.y; 94 | newDef.z = currDef.x * sinval + currDef.z * cosval; 95 | 96 | _legs[i].shiftDefault(newDef); 97 | } 98 | } 99 | 100 | void shiftYaw(float angleDelta) 101 | { 102 | float sinval = sin(angleDelta); 103 | float cosval = cos(angleDelta); 104 | 105 | for (byte i = 0; i < _legCount; ++i) 106 | { 107 | Point currDef = _legs[i].getDefaultPos(); 108 | Point newDef; 109 | newDef.x = currDef.x * cosval - currDef.y * sinval; 110 | newDef.y = currDef.x * sinval + currDef.y * cosval; 111 | newDef.z = currDef.z; 112 | 113 | _legs[i].shiftDefault(newDef); 114 | } 115 | } 116 | 117 | void shiftReset() 118 | { 119 | const int steps = 20; 120 | Point currDefs[_legCount]; 121 | 122 | for (byte i = 0; i < _legCount; ++i) 123 | currDefs[i] = _legs[i].getDefaultPos(); 124 | 125 | for (byte si = 0; si < steps; ++si) 126 | { 127 | for (byte i = 0; i < _legCount; ++i) 128 | { 129 | Point step = (_defaultPositions[i] - currDefs[i]) / steps; 130 | _legs[i].shiftDefaultRelative(step); 131 | } 132 | 133 | delay(2); 134 | } 135 | 136 | // Prevent default migration 137 | for (byte i = 0; i < _legCount; ++i) 138 | _legs[i].shiftDefault(_defaultPositions[i]); 139 | } 140 | 141 | float rotate(int steps, float clockwise, float startProgress = 0, bool (*pContinue)() = NULL) 142 | { 143 | float p = startProgress; 144 | for (int i = 0; i < steps; i++) 145 | { 146 | for(; p <= 2; /*p += 0.025*/) 147 | { 148 | float progress; 149 | float h[2]; // height 150 | float s[2]; // sine 151 | float c[2]; // cosine 152 | const float angle = clockwise * (PI / 500); 153 | 154 | if (p < 1) 155 | { 156 | progress = p; 157 | h[0] = 0; 158 | h[1] = 50 * (0.5 - fabs(0.5 - p)); 159 | s[0] = sin(angle); 160 | c[0] = cos(angle); 161 | s[1] = sin(- angle); 162 | c[1] = cos(- angle); 163 | } 164 | else 165 | { 166 | progress = 1 - (p - 1); 167 | h[0] = 50 * (0.5 - fabs(1.5 - p)); 168 | h[1] = 0; 169 | s[0] = sin(- angle); 170 | c[0] = cos(- angle); 171 | s[1] = sin(angle); 172 | c[1] = cos(angle); 173 | } 174 | 175 | for (int li = 0; li < _legCount; ++li) 176 | { 177 | // li - leg index, gi - group index 178 | int gi = li % 2; 179 | Point pNew; 180 | Point pCurr = _legs[li].getCurrentPos(); 181 | 182 | pNew.x = pCurr.x * c[gi] - pCurr.y * s[gi]; 183 | pNew.y = pCurr.x * s[gi] + pCurr.y * c[gi]; 184 | 185 | // Calc default pos 186 | pNew.x -= _legs[li].getDefaultPos().x; 187 | pNew.y -= _legs[li].getDefaultPos().y; 188 | pNew.z = h[gi]; 189 | 190 | _legs[li].reachRelativeToDefault(pNew); 191 | } 192 | 193 | delay(1); 194 | if (pContinue != NULL && ! pContinue()) 195 | return p; 196 | 197 | p += _speedFactor /*+ 0.00 * (0.5 - fabs(0.5 - progress))*/; 198 | } 199 | 200 | if (p > 2) 201 | p = 0; 202 | } 203 | 204 | return p; 205 | } 206 | 207 | void smoothTo(Point& to) 208 | { 209 | smoothTo(to, 0); 210 | smoothTo(to, 1); 211 | } 212 | 213 | // Relative to default! 214 | void smoothTo(Point& to, int legGroup) 215 | { 216 | Point relative[_legCount]; 217 | Point currentPositions[_legCount]; 218 | for (int i = legGroup; i < _legCount; i += 2) 219 | { 220 | currentPositions[i] = _legs[i].getCurrentPos(); 221 | relative[i].assign((_legs[i].getDefaultPos() + to) - _legs[i].getCurrentPos()); 222 | } 223 | 224 | for(float p = 0; p <= 1; p += 0.03) 225 | { 226 | for (int li = legGroup; li < _legCount; li += 2) 227 | { 228 | Point currSubStep = relative[li] * p; 229 | Point currStep = currentPositions[li] + currSubStep; 230 | currStep.z = _legs[li].getDefaultPos().z + to.z + 50 * (0.5 - fabs(0.5 - p)); 231 | _legs[li].reachAbsolute(currStep); 232 | } 233 | 234 | delay(5); 235 | } 236 | } 237 | 238 | private: 239 | 240 | Leg* _legs; 241 | const int _legCount; 242 | Leg* _mandibles; 243 | const int _mandibleCount; 244 | 245 | // FIXME 246 | Point _defaultPositions[6]; 247 | Point _defaultMandiblePositions[2]; 248 | 249 | Point _linearShift; 250 | 251 | float _speedFactor; 252 | }; 253 | 254 | #endif 255 | 256 | 257 | 258 | -------------------------------------------------------------------------------- /Buggy/SmoothFloat.h: -------------------------------------------------------------------------------- 1 | #ifndef SMOOTH_FLOAT_H__ 2 | #define SMOOTH_FLOAT_H__ 3 | 4 | #include "Geometry.h" 5 | 6 | class SmoothFloat 7 | { 8 | public: 9 | 10 | SmoothFloat(float target, float current) 11 | : _target(target) 12 | , _current(current) 13 | {} 14 | 15 | void setTarget(float target) 16 | { 17 | _target = target; 18 | } 19 | 20 | float getCurrent() 21 | { 22 | return _current; 23 | } 24 | 25 | float getCurrent(float stepDeltaOrig) 26 | { 27 | float stepDelta; 28 | const float dist = abs(_current - _target); 29 | if (dist < stepDeltaOrig * 5) 30 | stepDelta = stepDeltaOrig * 0.2; 31 | else if (dist < stepDeltaOrig * 2) 32 | stepDelta = stepDeltaOrig * 0.1; 33 | else stepDelta = stepDeltaOrig; 34 | 35 | if (_current >= _target) 36 | _current = max(_target, _current - stepDelta); 37 | else 38 | _current = min(_target, _current + stepDelta); 39 | 40 | return _current; 41 | } 42 | 43 | private: 44 | 45 | float _target; 46 | float _current; 47 | }; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /BuggyRemote/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /BuggyRemote/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | BuggyRemote 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | -------------------------------------------------------------------------------- /BuggyRemote/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 3 | org.eclipse.jdt.core.compiler.compliance=1.6 4 | org.eclipse.jdt.core.compiler.source=1.6 5 | org.eclipse.jdt.core.formatter.align_type_members_on_columns=false 6 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 7 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 8 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 9 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 10 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 11 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 12 | org.eclipse.jdt.core.formatter.alignment_for_assignment=0 13 | org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 14 | org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 15 | org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 16 | org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 17 | org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 18 | org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 19 | org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 20 | org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 21 | org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 22 | org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 23 | org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 24 | org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 25 | org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 26 | org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 27 | org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 28 | org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 29 | org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 30 | org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 31 | org.eclipse.jdt.core.formatter.blank_lines_after_package=1 32 | org.eclipse.jdt.core.formatter.blank_lines_before_field=0 33 | org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 34 | org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 35 | org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 36 | org.eclipse.jdt.core.formatter.blank_lines_before_method=1 37 | org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 38 | org.eclipse.jdt.core.formatter.blank_lines_before_package=0 39 | org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 40 | org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 41 | org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=next_line 42 | org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=next_line 43 | org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=next_line 44 | org.eclipse.jdt.core.formatter.brace_position_for_block=next_line 45 | org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=next_line 46 | org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line 47 | org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=next_line 48 | org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=next_line 49 | org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line 50 | org.eclipse.jdt.core.formatter.brace_position_for_switch=next_line 51 | org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line 52 | org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false 53 | org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false 54 | org.eclipse.jdt.core.formatter.comment.format_block_comments=true 55 | org.eclipse.jdt.core.formatter.comment.format_header=false 56 | org.eclipse.jdt.core.formatter.comment.format_html=true 57 | org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true 58 | org.eclipse.jdt.core.formatter.comment.format_line_comments=true 59 | org.eclipse.jdt.core.formatter.comment.format_source_code=true 60 | org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true 61 | org.eclipse.jdt.core.formatter.comment.indent_root_tags=true 62 | org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert 63 | org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert 64 | org.eclipse.jdt.core.formatter.comment.line_length=80 65 | org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true 66 | org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true 67 | org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false 68 | org.eclipse.jdt.core.formatter.compact_else_if=true 69 | org.eclipse.jdt.core.formatter.continuation_indentation=2 70 | org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 71 | org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off 72 | org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on 73 | org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false 74 | org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true 75 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true 76 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true 77 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true 78 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true 79 | org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true 80 | org.eclipse.jdt.core.formatter.indent_empty_lines=false 81 | org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true 82 | org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true 83 | org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true 84 | org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false 85 | org.eclipse.jdt.core.formatter.indentation.size=4 86 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert 87 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert 88 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert 89 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert 90 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert 91 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert 92 | org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert 93 | org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert 94 | org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert 95 | org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert 96 | org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert 97 | org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert 98 | org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert 99 | org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert 100 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=do not insert 101 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert 102 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=do not insert 103 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=do not insert 104 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=do not insert 105 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=do not insert 106 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=do not insert 107 | org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert 108 | org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert 109 | org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert 110 | org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert 111 | org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert 112 | org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert 113 | org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert 114 | org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert 115 | org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert 116 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert 117 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert 118 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert 119 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert 120 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert 121 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert 122 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert 123 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert 124 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert 125 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert 126 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert 127 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert 128 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert 129 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert 130 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert 131 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert 132 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert 133 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert 134 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert 135 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert 136 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert 137 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert 138 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert 139 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert 140 | org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert 141 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert 142 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert 143 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert 144 | org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert 145 | org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert 146 | org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert 147 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert 148 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert 149 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert 150 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert 151 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert 152 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert 153 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert 154 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert 155 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert 156 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert 157 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert 158 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert 159 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert 160 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert 161 | org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert 162 | org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert 163 | org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert 164 | org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert 165 | org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert 166 | org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert 167 | org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert 168 | org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert 169 | org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert 170 | org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert 171 | org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert 172 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert 173 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert 174 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert 175 | org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert 176 | org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert 177 | org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert 178 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert 179 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert 180 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert 181 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert 182 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert 183 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert 184 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert 185 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert 186 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert 187 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert 188 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert 189 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert 190 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert 191 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert 192 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert 193 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert 194 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert 195 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert 196 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert 197 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert 198 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert 199 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert 200 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert 201 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert 202 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert 203 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert 204 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert 205 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert 206 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert 207 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert 208 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert 209 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert 210 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert 211 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert 212 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert 213 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert 214 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert 215 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert 216 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert 217 | org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert 218 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert 219 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert 220 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert 221 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert 222 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert 223 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert 224 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert 225 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert 226 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert 227 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert 228 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert 229 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert 230 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert 231 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert 232 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert 233 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert 234 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert 235 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert 236 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert 237 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert 238 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert 239 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert 240 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert 241 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert 242 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert 243 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert 244 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert 245 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert 246 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert 247 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert 248 | org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert 249 | org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert 250 | org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert 251 | org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert 252 | org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert 253 | org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert 254 | org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert 255 | org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert 256 | org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert 257 | org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert 258 | org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert 259 | org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert 260 | org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert 261 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert 262 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert 263 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert 264 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert 265 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert 266 | org.eclipse.jdt.core.formatter.join_lines_in_comments=true 267 | org.eclipse.jdt.core.formatter.join_wrapped_lines=true 268 | org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false 269 | org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false 270 | org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false 271 | org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false 272 | org.eclipse.jdt.core.formatter.lineSplit=80 273 | org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false 274 | org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false 275 | org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 276 | org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 277 | org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true 278 | org.eclipse.jdt.core.formatter.tabulation.char=space 279 | org.eclipse.jdt.core.formatter.tabulation.size=4 280 | org.eclipse.jdt.core.formatter.use_on_off_tags=false 281 | org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false 282 | org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true 283 | org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true 284 | org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true 285 | -------------------------------------------------------------------------------- /BuggyRemote/.settings/org.eclipse.jdt.ui.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true 3 | formatter_profile=_Nocco 4 | formatter_settings_version=12 5 | sp_cleanup.add_default_serial_version_id=true 6 | sp_cleanup.add_generated_serial_version_id=false 7 | sp_cleanup.add_missing_annotations=true 8 | sp_cleanup.add_missing_deprecated_annotations=true 9 | sp_cleanup.add_missing_methods=false 10 | sp_cleanup.add_missing_nls_tags=false 11 | sp_cleanup.add_missing_override_annotations=true 12 | sp_cleanup.add_missing_override_annotations_interface_methods=true 13 | sp_cleanup.add_serial_version_id=false 14 | sp_cleanup.always_use_blocks=true 15 | sp_cleanup.always_use_parentheses_in_expressions=false 16 | sp_cleanup.always_use_this_for_non_static_field_access=false 17 | sp_cleanup.always_use_this_for_non_static_method_access=false 18 | sp_cleanup.convert_to_enhanced_for_loop=true 19 | sp_cleanup.correct_indentation=false 20 | sp_cleanup.format_source_code=false 21 | sp_cleanup.format_source_code_changes_only=false 22 | sp_cleanup.make_local_variable_final=true 23 | sp_cleanup.make_parameters_final=true 24 | sp_cleanup.make_private_fields_final=true 25 | sp_cleanup.make_type_abstract_if_missing_method=false 26 | sp_cleanup.make_variable_declarations_final=true 27 | sp_cleanup.never_use_blocks=false 28 | sp_cleanup.never_use_parentheses_in_expressions=true 29 | sp_cleanup.on_save_use_additional_actions=true 30 | sp_cleanup.organize_imports=true 31 | sp_cleanup.qualify_static_field_accesses_with_declaring_class=false 32 | sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true 33 | sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true 34 | sp_cleanup.qualify_static_member_accesses_with_declaring_class=false 35 | sp_cleanup.qualify_static_method_accesses_with_declaring_class=false 36 | sp_cleanup.remove_private_constructors=true 37 | sp_cleanup.remove_trailing_whitespaces=true 38 | sp_cleanup.remove_trailing_whitespaces_all=true 39 | sp_cleanup.remove_trailing_whitespaces_ignore_empty=false 40 | sp_cleanup.remove_unnecessary_casts=true 41 | sp_cleanup.remove_unnecessary_nls_tags=false 42 | sp_cleanup.remove_unused_imports=false 43 | sp_cleanup.remove_unused_local_variables=false 44 | sp_cleanup.remove_unused_private_fields=true 45 | sp_cleanup.remove_unused_private_members=false 46 | sp_cleanup.remove_unused_private_methods=true 47 | sp_cleanup.remove_unused_private_types=true 48 | sp_cleanup.sort_members=false 49 | sp_cleanup.sort_members_all=false 50 | sp_cleanup.use_blocks=false 51 | sp_cleanup.use_blocks_only_for_return_and_throw=false 52 | sp_cleanup.use_parentheses_in_expressions=true 53 | sp_cleanup.use_this_for_non_static_field_access=false 54 | sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true 55 | sp_cleanup.use_this_for_non_static_method_access=false 56 | sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true 57 | -------------------------------------------------------------------------------- /BuggyRemote/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 16 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /BuggyRemote/gen/com/poconoco/buggyremote/BuildConfig.java: -------------------------------------------------------------------------------- 1 | /** Automatically generated file. DO NOT MODIFY */ 2 | package com.poconoco.buggyremote; 3 | 4 | public final class BuildConfig { 5 | public final static boolean DEBUG = true; 6 | } -------------------------------------------------------------------------------- /BuggyRemote/gen/com/poconoco/buggyremote/R.java: -------------------------------------------------------------------------------- 1 | /* AUTO-GENERATED FILE. DO NOT MODIFY. 2 | * 3 | * This class was automatically generated by the 4 | * aapt tool from the resource data it found. It 5 | * should not be modified by hand. 6 | */ 7 | 8 | package com.poconoco.buggyremote; 9 | 10 | public final class R { 11 | public static final class attr { 12 | } 13 | public static final class drawable { 14 | public static final int ic_launcher=0x7f020000; 15 | } 16 | public static final class id { 17 | public static final int bodyShiftArea=0x7f07000c; 18 | public static final int buttonBT=0x7f070000; 19 | public static final int buttonEngine=0x7f070001; 20 | public static final int buttonGait1=0x7f070009; 21 | public static final int buttonGait2=0x7f07000a; 22 | public static final int buttonGait3=0x7f07000b; 23 | public static final int buttonMandiblesEngine=0x7f070002; 24 | public static final int checkBoxHorizShift=0x7f070007; 25 | public static final int checkBoxMandibleControl=0x7f070008; 26 | public static final int checkBoxSensors=0x7f070005; 27 | public static final int checkLinear=0x7f070006; 28 | public static final int menu_settings=0x7f07000e; 29 | public static final int movementAreaImage=0x7f070004; 30 | public static final int movementHint=0x7f07000d; 31 | public static final int seekMandibleHeight=0x7f070003; 32 | } 33 | public static final class layout { 34 | public static final int activity_main=0x7f030000; 35 | } 36 | public static final class menu { 37 | public static final int activity_main=0x7f060000; 38 | } 39 | public static final class string { 40 | public static final int app_name=0x7f040000; 41 | public static final int hello_world=0x7f040001; 42 | public static final int menu_settings=0x7f040002; 43 | } 44 | public static final class style { 45 | /** 46 | Base application theme, dependent on API level. This theme is replaced 47 | by AppBaseTheme from res/values-vXX/styles.xml on newer devices. 48 | 49 | 50 | Theme customizations available in newer API levels can go in 51 | res/values-vXX/styles.xml, while customizations related to 52 | backward-compatibility can go here. 53 | 54 | 55 | Base application theme for API 11+. This theme completely replaces 56 | AppBaseTheme from res/values/styles.xml on API 11+ devices. 57 | 58 | API 11 theme customizations can go here. 59 | 60 | Base application theme for API 14+. This theme completely replaces 61 | AppBaseTheme from BOTH res/values/styles.xml and 62 | res/values-v11/styles.xml on API 14+ devices. 63 | 64 | API 14 theme customizations can go here. 65 | */ 66 | public static final int AppBaseTheme=0x7f050000; 67 | /** Application theme. 68 | All customizations that are NOT specific to a particular API-level can go here. 69 | */ 70 | public static final int AppTheme=0x7f050001; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /BuggyRemote/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poconoco/buggybug/e7266174e84d15f5d7663db48edffc381526da1e/BuggyRemote/ic_launcher-web.png -------------------------------------------------------------------------------- /BuggyRemote/libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poconoco/buggybug/e7266174e84d15f5d7663db48edffc381526da1e/BuggyRemote/libs/android-support-v4.jar -------------------------------------------------------------------------------- /BuggyRemote/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /BuggyRemote/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-17 15 | -------------------------------------------------------------------------------- /BuggyRemote/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poconoco/buggybug/e7266174e84d15f5d7663db48edffc381526da1e/BuggyRemote/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /BuggyRemote/res/drawable-ldpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poconoco/buggybug/e7266174e84d15f5d7663db48edffc381526da1e/BuggyRemote/res/drawable-ldpi/ic_launcher.png -------------------------------------------------------------------------------- /BuggyRemote/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poconoco/buggybug/e7266174e84d15f5d7663db48edffc381526da1e/BuggyRemote/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /BuggyRemote/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poconoco/buggybug/e7266174e84d15f5d7663db48edffc381526da1e/BuggyRemote/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /BuggyRemote/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 15 | 16 | 19 | 20 |