Mercurial > ukubik
changeset 55:5ce82161111d
do average of acceleration
| author | Radomir Dopieralski <sheep-devel@sheep.art.pl> |
|---|---|
| date | Sun, 24 Aug 2014 14:27:09 +0200 |
| parents | fb9cfdc1cf12 |
| children | 008236195f5a |
| files | robot.py servo.py servo/servo.ino |
| diffstat | 3 files changed, 116 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/robot.py Sat Aug 23 20:32:26 2014 +0200 +++ b/robot.py Sun Aug 24 14:27:09 2014 +0200 @@ -60,6 +60,9 @@ values[i] = int(float(sum(a[i] for a in accels)) / probes - self.accel_trim[i]) return values + def beep(self, frequency, duration): + self.legs[0].hip.beep(frequency, duration) + def _run_animations(self, animations, fps=12): clock = pygame.time.Clock() while animations:
--- a/servo.py Sat Aug 23 20:32:26 2014 +0200 +++ b/servo.py Sun Aug 24 14:27:09 2014 +0200 @@ -46,6 +46,13 @@ pass return [ord(c) for c in self.serial.read(3)] + def beep(self, frequency, duration): + command = '\xf1' + self.serial.write(command) + self.serial.write('%c' % (frequency & 0xff)) + self.serial.write('%c' % (frequency >> 8 & 0xff)) + self.serial.write('%c' % duration) + def calculate_angle(self): position = self.position if self.reverse:
--- a/servo/servo.ino Sat Aug 23 20:32:26 2014 +0200 +++ b/servo/servo.ino Sun Aug 24 14:27:09 2014 +0200 @@ -3,13 +3,11 @@ */ #include <Servo.h> +#include <math.h> // Number of servos in legs. #define MAX_SERVO 12 -// Home position of the servos. -#define HOME_POS 90 - // Range of the servos. #define SERVO_FREQ_MIN 600 #define SERVO_FREQ_MAX 2400 @@ -17,22 +15,89 @@ // 3.3V maximum for the acceleration sensor. #define ACCEL_MAX 676 +// How many acceleration measurements to cache. +#define MAX_ACCEL_BUFFER 16 + // Speed of the serial port. #define SERIAL_SPEED 9600 // 115200 // 38400 // 9600 +// Leg dimensions. +#define LEG_COXA 22.5 +#define LEG_FEMUR 38.0 +#define LEG_TIBIA 30.0 +#define LEG_BASE 15.0 + +int joints[12][2] { +// reverse, trim + {1, 50}, + {-1, -50}, + {1, 0}, + {-1, 0}, + {1, -80}, + {-1, 0}, + {1, 50}, + {-1, 0}, + {-1, 0}, + {1, 0}, + {1, 0}, + {-1, 0}, +}; +int legs[4][5] = { +// hip, knee, ankle, x_direction, y_direction + {11, 4, 0, -1, -1}, + {8, 7, 3, -1, 1}, + {9, 6, 2, 1, 1}, + {10, 5, 1, 1, -1}, +}; Servo servos[MAX_SERVO]; int serial_command = 0; +int accel_buffer[MAX_ACCEL_BUFFER][3]; +int accel_buffer_index = 0; +unsigned long last_tick = 0; +void read_accel() { + accel_buffer[accel_buffer_index][0] = analogRead(A2); + accel_buffer[accel_buffer_index][1] = analogRead(A1); + accel_buffer[accel_buffer_index][2] = analogRead(A0); + accel_buffer_index = (accel_buffer_index + 1) % MAX_ACCEL_BUFFER; +} + int _serial_read_word() { /* Read two bytes from the serial port and make an int from them. */ return Serial.read() | Serial.read() << 8; } +double _norm(double a, double b) { + return sqrt(a * a + b * b); +} + +double _triangle(double a, double b, double c) { + return facos((a * a + b * b - c * c) / (2 * a * b)); +} + +int _radians_to_microseconds(double angle) { + while (angle < 0) { + angle += 2; + } + return SERVO_FREQ_MIN + (SERVO_FREQ_MAX - SERVO_FREQ_MIN) * angle; +} + +void move_leg(int leg, double x, double y, double z) { + double f = _norm(x, y) - LEG_COXA; + double d = _norm(f, z); + double hip = fatan2(y, x) + 0.25 * legs[leg][4]; + double knee = fatan2(-z, f) - _triangle(LEG_FEMUR, d, LEG_TIBIA); + double ankle = _triangle(LEG_FEMUR, LEG_TIBIA, d) - 0.5; + servos[legs[leg][0]].writeMicroseconds(_radians_to_microseconds(hip)); + servos[legs[leg][1]].writeMicroseconds(_radians_to_microseconds(knee)); + servos[legs[leg][2]].writeMicroseconds(_radians_to_microseconds(ankle)); +} + void do_servo_degrees() { /* Move a single servo by degrees. */ int servo = Serial.read(); @@ -72,12 +137,31 @@ } } +void do_move_leg() { + /* Move the leg to a position in space. */ + int leg = Serial.read(); + int x = Serial.read() - 128; + int y = Serial.read() - 128; + int z = Serial.read() - 128; + if (leg >= 0 && leg <= 4) { + move_leg(leg, x, y, z); + } +} + void do_accel() { /* Report the readings of the acceleration sensor. */ + int x = 0; + int y = 0; + int z = 0; + for (int i = 0; i < MAX_ACCEL_BUFFER; i += 1) { + x += accel_buffer[i][0]; + y += accel_buffer[i][0]; + z += accel_buffer[i][0]; + } Serial.write(0xff); - Serial.write(map(analogRead(A2), 0, 676, 0, 255)); - Serial.write(map(analogRead(A1), 0, 676, 0, 255)); - Serial.write(map(analogRead(A0), 0, 676, 0, 255)); + Serial.write(map(x / MAX_ACCEL_BUFFER, 0, 676, 0, 255)); + Serial.write(map(y / MAX_ACCEL_BUFFER, 0, 676, 0, 255)); + Serial.write(map(z / MAX_ACCEL_BUFFER, 0, 676, 0, 255)); } void do_beep() { @@ -124,6 +208,13 @@ } do_servos_microseconds(); break; + case 0xfb: + /* Move a leg to a position in space. */ + if (Serial.available() < 4) { + return; + } + do_move_leg(); + break; case 0xf0: /* Read the accelerometer sensor. */ do_accel(); @@ -146,12 +237,20 @@ for (servo = 0; servo < MAX_SERVO; servo += 1) { /* First 2 pins are used for the serial. */ servos[servo].attach(servo + 2, SERVO_FREQ_MIN, SERVO_FREQ_MAX); - servos[servo].write(HOME_POS); + servos[servo].writeMicroseconds(1500); /* Don't set all servos at once, save power. */ delay(150); } } void loop() { + unsigned long now = millis(); + do_serial_command(); +/* + if (now > last_tick + 100 || now < last_tick) { + read_accel(); + last_tick = now; + } +*/ }
