├── BuggyRemote ├── ic_launcher-web.png ├── libs │ └── android-support-v4.jar ├── res │ ├── drawable-hdpi │ │ └── ic_launcher.png │ ├── drawable-ldpi │ │ └── ic_launcher.png │ ├── drawable-mdpi │ │ └── ic_launcher.png │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ ├── values │ │ ├── strings.xml │ │ └── styles.xml │ ├── menu │ │ └── activity_main.xml │ ├── values-v11 │ │ └── styles.xml │ ├── values-v14 │ │ └── styles.xml │ └── layout │ │ └── activity_main.xml ├── gen │ └── com │ │ └── poconoco │ │ └── buggyremote │ │ ├── BuildConfig.java │ │ └── R.java ├── .classpath ├── project.properties ├── proguard-project.txt ├── .project ├── AndroidManifest.xml ├── src │ └── com │ │ └── poconoco │ │ └── buggyremote │ │ ├── BuggyBodyShift.java │ │ ├── BuggyProtocol.java │ │ ├── BuggyMandibles.java │ │ ├── BuggyBodyMovement.java │ │ ├── BuggySensors.java │ │ ├── MainActivity.java │ │ └── BuggyBluetooth.java └── .settings │ ├── org.eclipse.jdt.ui.prefs │ └── org.eclipse.jdt.core.prefs ├── .gitignore ├── README.md ├── serial_interface.txt └── Buggy ├── SmoothFloat.h ├── Mark1Config.h ├── Geometry.h ├── Mark2Config.h ├── Buggy.ino ├── SimpleMovements.h ├── Gait2.h └── Leg.h /BuggyRemote/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poconoco/buggybug/HEAD/BuggyRemote/ic_launcher-web.png -------------------------------------------------------------------------------- /BuggyRemote/libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poconoco/buggybug/HEAD/BuggyRemote/libs/android-support-v4.jar -------------------------------------------------------------------------------- /BuggyRemote/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poconoco/buggybug/HEAD/BuggyRemote/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /BuggyRemote/res/drawable-ldpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poconoco/buggybug/HEAD/BuggyRemote/res/drawable-ldpi/ic_launcher.png -------------------------------------------------------------------------------- /BuggyRemote/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poconoco/buggybug/HEAD/BuggyRemote/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /BuggyRemote/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poconoco/buggybug/HEAD/BuggyRemote/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | buggybug 2 | ======== 3 | 4 | Hexapod firmware sources 5 | 6 | - master branch contains bluetooth controlled version, 7 | - flysky branch - PWM RC controlled version, tuned for FlySky-iA6 receiver 8 | -------------------------------------------------------------------------------- /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/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | BuggyRC 5 | Hello world! 6 | Settings 7 | 8 | -------------------------------------------------------------------------------- /BuggyRemote/res/menu/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /BuggyRemote/res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /BuggyRemote/res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /BuggyRemote/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /serial_interface.txt: -------------------------------------------------------------------------------- 1 | Serial commands with one character: 2 | 3 | " " - (single space, no quotes) attach/detach all leg servos 4 | "_" - (single underline, no quotes) attach/detach mandible servos 5 | 6 | Multibyte commands: 7 | 8 | bB - body shift, x, y and z are signed bytes, 0 are centers 9 | mM - movement, x, y are signed bytes, Turn is signed byte (o - no turn), Speed - unsigned byte 10 | gG 11 | pP - mandible movement, right and left independently 12 | -------------------------------------------------------------------------------- /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/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | -------------------------------------------------------------------------------- /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: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /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/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 16 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /BuggyRemote/src/com/poconoco/buggyremote/BuggyBodyShift.java: -------------------------------------------------------------------------------- 1 | package com.poconoco.buggyremote; 2 | 3 | public class BuggyBodyShift 4 | { 5 | public byte x = 0; 6 | public byte y = 0; 7 | public byte z = 0; 8 | public byte pitch = 0; 9 | public byte roll = 0; 10 | public byte yaw = 0; 11 | 12 | public void copyFrom(final BuggyBodyShift src) 13 | { 14 | x = src.x; 15 | y = src.y; 16 | z = src.z; 17 | pitch = src.pitch; 18 | roll = src.roll; 19 | yaw = src.yaw; 20 | } 21 | 22 | public boolean differ(final BuggyBodyShift arg) 23 | { 24 | if (arg == null) 25 | return true; 26 | 27 | final byte angleMargin = 0; 28 | final byte linearMargin = 0; 29 | 30 | return !(withinMargin(x, arg.x, linearMargin) 31 | && withinMargin(y, arg.y, linearMargin) 32 | && withinMargin(z, arg.z, linearMargin) 33 | && withinMargin(pitch, arg.pitch, angleMargin) 34 | && withinMargin(roll, arg.roll, angleMargin) 35 | && withinMargin(yaw, arg.yaw, angleMargin)); 36 | } 37 | 38 | private boolean withinMargin(final byte a1, final byte a2, final byte margin) 39 | { 40 | return Math.abs(a1 - a2) <= margin; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /BuggyRemote/src/com/poconoco/buggyremote/BuggyProtocol.java: -------------------------------------------------------------------------------- 1 | package com.poconoco.buggyremote; 2 | 3 | public class BuggyProtocol 4 | { 5 | public static byte[] getToggleServoCmd() 6 | { 7 | return new byte[] {' '}; 8 | } 9 | 10 | public static byte[] getToggleMandibleCmd() 11 | { 12 | return new byte[] {'_'}; 13 | } 14 | 15 | public static byte[] getGaitCmd(final int gait) 16 | { 17 | return new byte[] { 'g', (byte) gait, 'G'}; 18 | } 19 | 20 | public static byte[] getBodyShiftCmd(final BuggyBodyShift bodyShift) 21 | { 22 | final byte[] cmd = new byte[8]; 23 | 24 | cmd[0] = 'b'; 25 | 26 | cmd[1] = bodyShift.x; 27 | cmd[2] = bodyShift.y; 28 | cmd[3] = bodyShift.z; 29 | 30 | cmd[4] = bodyShift.pitch; 31 | cmd[5] = bodyShift.roll; 32 | cmd[6] = bodyShift.yaw; 33 | 34 | cmd[7] = 'B'; 35 | 36 | return cmd; 37 | } 38 | 39 | public static byte[] getBodyMovementCmd(final BuggyBodyMovement bodyMovement) 40 | { 41 | final byte[] cmd = new byte[6]; 42 | 43 | cmd[0] = 'm'; 44 | 45 | cmd[1] = bodyMovement.x; 46 | cmd[2] = bodyMovement.y; 47 | cmd[3] = bodyMovement.turn; 48 | cmd[4] = bodyMovement.speed; 49 | 50 | cmd[5] = 'M'; 51 | 52 | return cmd; 53 | } 54 | 55 | public static byte[] getMandiblesCmd(final BuggyMandibles mandibles) 56 | { 57 | final byte[] cmd = new byte[8]; 58 | 59 | cmd[0] = 'p'; 60 | 61 | cmd[1] = mandibles.rx; 62 | cmd[2] = mandibles.ry; 63 | cmd[3] = mandibles.rz; 64 | 65 | cmd[4] = mandibles.lx; 66 | cmd[5] = mandibles.ly; 67 | cmd[6] = mandibles.lz; 68 | 69 | cmd[7] = 'P'; 70 | 71 | return cmd; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /BuggyRemote/src/com/poconoco/buggyremote/BuggyMandibles.java: -------------------------------------------------------------------------------- 1 | package com.poconoco.buggyremote; 2 | 3 | public class BuggyMandibles 4 | { 5 | public byte rx = 0; 6 | public byte ry = 0; 7 | public byte rz = 0; 8 | 9 | public byte lx = 0; 10 | public byte ly = 0; 11 | public byte lz = 0; 12 | 13 | public void copyFrom(final BuggyMandibles src) 14 | { 15 | rx = src.rx; 16 | ry = src.ry; 17 | rz = src.rz; 18 | lx = src.lx; 19 | ly = src.ly; 20 | lz = src.lz; 21 | } 22 | 23 | // all args are -1..1 24 | public void encodeRight(final double joystickRX, 25 | final double joystickRY) 26 | { 27 | rx = (byte) (joystickRX * 127.0); 28 | rz = (byte) (joystickRY * 127.0); 29 | } 30 | 31 | // all args are -1..1 32 | public void encodeLeft(final double joystickLX, 33 | final double joystickLY) 34 | { 35 | lx = (byte) (joystickLX * 127.0); 36 | lz = (byte) (joystickLY * 127.0); 37 | } 38 | 39 | // all args are -1..1 40 | public void encodeHeight(final double height) 41 | { 42 | ry = (byte) (height * 127.0); 43 | ly = (byte) (height * 127.0); 44 | } 45 | 46 | public boolean differ(final BuggyMandibles arg) 47 | { 48 | if (arg == null) 49 | return true; 50 | 51 | final byte linearMargin = 0; 52 | 53 | return !(withinMargin(rx, arg.rx, linearMargin) 54 | && withinMargin(ry, arg.ry, linearMargin) 55 | && withinMargin(rz, arg.rz, linearMargin) 56 | && withinMargin(lx, arg.lx, linearMargin) 57 | && withinMargin(ly, arg.ly, linearMargin) 58 | && withinMargin(lz, arg.lz, linearMargin)); 59 | } 60 | 61 | private boolean withinMargin(final byte a1, final byte a2, final byte margin) 62 | { 63 | return Math.abs(a1 - a2) <= margin; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /BuggyRemote/src/com/poconoco/buggyremote/BuggyBodyMovement.java: -------------------------------------------------------------------------------- 1 | package com.poconoco.buggyremote; 2 | 3 | public class BuggyBodyMovement 4 | { 5 | public byte x; 6 | public byte y; 7 | public byte turn; 8 | public byte speed; 9 | 10 | // joystick* are -1..1 11 | public void encodeLinear(final double joystickX, final double joystickY_) 12 | { 13 | final double joystickY = - joystickY_; 14 | final double length = Math.sqrt(joystickX * joystickX + joystickY 15 | * joystickY); 16 | 17 | if (length < 0.0001) 18 | { 19 | speed = 0; 20 | x = 0; 21 | y = 0; 22 | turn = 0; 23 | return; 24 | } 25 | 26 | speed = (byte) (length * 127); 27 | 28 | x = (byte) (joystickX * (1.0 / length) * 127.0); 29 | y = (byte) (joystickY * (1.0 / length) * 127.0); 30 | 31 | final double slowTreshold = 0.1; 32 | if (length < slowTreshold) 33 | { 34 | final double breaking = 1 - (slowTreshold - length) 35 | / slowTreshold; 36 | 37 | x = (byte) (x * breaking); 38 | y = (byte) (y * breaking); 39 | } 40 | 41 | turn = 0; 42 | } 43 | 44 | // joystick* are -1..1 45 | public void encodeWithTurn(final double joystickX_, final double joystickY_) 46 | { 47 | final double joystickX = 0; 48 | final double joystickY = - joystickY_; 49 | 50 | final double length = Math.sqrt(joystickX * joystickX + joystickY 51 | * joystickY); 52 | 53 | if (length < 0.0001) 54 | { 55 | speed = 0; 56 | x = 0; 57 | y = 0; 58 | turn = 0; 59 | return; 60 | } 61 | 62 | speed = (byte) (length * 127); 63 | 64 | x = (byte) (joystickX * (1.0 / length) * 127.0); 65 | y = (byte) (joystickY * (1.0 / length) * 127.0); 66 | 67 | final double slowTreshold = 0.1; 68 | if (length < slowTreshold) 69 | { 70 | final double breaking = 1 - (slowTreshold - length) 71 | / slowTreshold; 72 | 73 | x = (byte) (x * breaking); 74 | y = (byte) (y * breaking); 75 | return; 76 | } 77 | 78 | turn = (byte) (joystickX_ * 127); 79 | } 80 | 81 | public void copyFrom(final BuggyBodyMovement src) 82 | { 83 | x = src.x; 84 | y = src.y; 85 | turn = src.turn; 86 | speed = src.speed; 87 | } 88 | 89 | public boolean differ(final BuggyBodyMovement arg) 90 | { 91 | if (arg == null) 92 | return true; 93 | 94 | return x != arg.x || y != arg.y || turn != arg.turn 95 | || speed != arg.speed; 96 | 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /BuggyRemote/src/com/poconoco/buggyremote/BuggySensors.java: -------------------------------------------------------------------------------- 1 | package com.poconoco.buggyremote; 2 | 3 | import android.content.Context; 4 | import android.hardware.Sensor; 5 | import android.hardware.SensorEvent; 6 | import android.hardware.SensorEventListener; 7 | import android.hardware.SensorManager; 8 | 9 | public class BuggySensors 10 | implements SensorEventListener 11 | { 12 | public interface Listener 13 | { 14 | void onPitchRollChanged(float pitch, float roll); 15 | } 16 | 17 | BuggySensors(final Context context, final Listener listener) 18 | { 19 | _listener = listener; 20 | _context = context; 21 | 22 | register(); 23 | } 24 | 25 | public void unregister() 26 | { 27 | _sensorManager.unregisterListener(this); 28 | } 29 | 30 | public void register() 31 | { 32 | _sensorManager = (SensorManager) _context.getSystemService(Context.SENSOR_SERVICE); 33 | 34 | _sensorManager.registerListener(this, _sensorManager 35 | .getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), 36 | SensorManager.SENSOR_DELAY_GAME); 37 | _sensorManager 38 | .registerListener(this, _sensorManager 39 | .getDefaultSensor(Sensor.TYPE_ACCELEROMETER), 40 | SensorManager.SENSOR_DELAY_GAME); 41 | } 42 | 43 | @Override 44 | public void onAccuracyChanged(final Sensor sensor, final int accuracy) 45 | { 46 | } 47 | 48 | @Override 49 | public void onSensorChanged(final SensorEvent event) 50 | { 51 | if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) 52 | { 53 | accel(event); 54 | } 55 | if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) 56 | { 57 | mag(event); 58 | } 59 | } 60 | 61 | private void accel(final SensorEvent event) 62 | { 63 | if (_lastAccels == null) 64 | { 65 | _lastAccels = new float[3]; 66 | } 67 | 68 | System.arraycopy(event.values, 0, _lastAccels, 0, 3); 69 | 70 | /* 71 | * if (m_lastMagFields != null) { computeOrientation(); } 72 | */ 73 | } 74 | 75 | private void mag(final SensorEvent event) 76 | { 77 | if (_lastMagFields == null) 78 | { 79 | _lastMagFields = new float[3]; 80 | } 81 | 82 | System.arraycopy(event.values, 0, _lastMagFields, 0, 3); 83 | 84 | if (_lastAccels != null) 85 | { 86 | computeOrientation(); 87 | } 88 | } 89 | 90 | private void computeOrientation() 91 | { 92 | if (SensorManager.getRotationMatrix(_rotationMatrix, null, 93 | _lastAccels, _lastMagFields)) 94 | { 95 | SensorManager.getOrientation(_rotationMatrix, _orientation); 96 | 97 | /* 1 radian = 57.2957795 degrees */ 98 | /* 99 | * [0] : yaw, rotation around z axis [1] : pitch, rotation 100 | * around x axis [2] : roll, rotation around y axis 101 | */ 102 | final float yaw = _orientation[0] * 57.2957795f; 103 | final float pitch = _orientation[1] * 57.2957795f; 104 | final float roll = _orientation[2] * 57.2957795f; 105 | 106 | /* append returns an average of the last 10 values */ 107 | /* 108 | * m_lastYaw = m_filters[0].append(yaw); m_lastPitch = 109 | * m_filters[1].append(pitch); m_lastRoll = 110 | * m_filters[2].append(roll); 111 | */ 112 | _lastYaw = yaw; 113 | _lastPitch = pitch; 114 | _lastRoll = roll; 115 | 116 | _listener.onPitchRollChanged(limitTo90(_lastRoll), limitTo90(-_lastPitch)); 117 | } 118 | } 119 | 120 | private float limitTo90(final float angle) 121 | { 122 | if (angle < -90) 123 | return -90; 124 | if (angle > 90) 125 | return 90; 126 | 127 | return angle; 128 | } 129 | 130 | private final Listener _listener; 131 | private final Context _context; 132 | 133 | SensorManager _sensorManager; 134 | 135 | private float[] _lastMagFields; 136 | private float[] _lastAccels; 137 | private final float[] _rotationMatrix = new float[16]; 138 | private final float[] _orientation = new float[4]; 139 | 140 | float _lastPitch = 0.f; 141 | float _lastYaw = 0.f; 142 | float _lastRoll = 0.f; 143 | } 144 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /BuggyRemote/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 15 | 16 | 19 | 20 |