Skip to content

Commit

Permalink
Merge pull request #21 from dmt-labs/feature/v3serial
Browse files Browse the repository at this point in the history
Serial servo control
  • Loading branch information
danic85 authored Jul 18, 2023
2 parents ebbef47 + 66e0883 commit c6b23fe
Show file tree
Hide file tree
Showing 28 changed files with 687 additions and 117 deletions.
6 changes: 5 additions & 1 deletion .vscode/arduino.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
{
"port": "/dev/ttyS0"
"port": "/dev/ttyS0",
"configuration": "cpu=16MHzatmega328",
"board": "arduino:avr:pro",
"programmer": "avrisp",
"sketch": "arduino_sketch/arduino_sketch.ino"
}
539 changes: 539 additions & 0 deletions .vscode/c_cpp_properties.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions animations/head_nod.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
{"servo:tilt:mv": -10},
{"sleep": 0.5},
{"servo:tilt:mv": 20},
{"sleep": 0.2},
{"sleep": 0.5},
{"servo:tilt:mv": -20},
{"sleep": 0.2},
{"sleep": 0.5},
{"servo:tilt:mv": 20},
{"sleep": 0.2},
{"sleep": 0.5},
{"servo:tilt:mv": -10},
{"sleep": 0.5}
]
12 changes: 12 additions & 0 deletions animations/head_nod_abs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
{"servo:tilt:mvabs": 70},
{"sleep": 0.4},
{"servo:tilt:mvabs": 30},
{"sleep": 0.4},
{"servo:tilt:mvabs": 70},
{"sleep": 0.4},
{"servo:tilt:mvabs": 30},
{"sleep": 0.4},
{"servo:tilt:mvabs": 50},
{"sleep": 0.5}
]
16 changes: 8 additions & 8 deletions animations/head_shake.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[
{"servo:pan:mv": -10},
{"sleep": 0.5},
{"servo:pan:mv": 20},
{"sleep": 0.2},
{"servo:pan:mv": -20},
{"sleep": 0.2},
{"sleep": 0.5},
{"servo:pan:mv": -40},
{"sleep": 0.5},
{"servo:pan:mv": 40},
{"sleep": 0.5},
{"servo:pan:mv": -40},
{"sleep": 0.5},
{"servo:pan:mv": 20},
{"sleep": 0.2},
{"servo:pan:mv": -10},
{"sleep": 0.5}
{"sleep": 2}
]
12 changes: 12 additions & 0 deletions animations/head_shake_abs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
{"servo:pan:mvabs": 40},
{"sleep": 0.4},
{"servo:pan:mvabs": 60},
{"sleep": 0.4},
{"servo:pan:mvabs": 40},
{"sleep": 0.4},
{"servo:pan:mvabs": 60},
{"sleep": 0.4},
{"servo:pan:mvabs": 50},
{"sleep": 2}
]
6 changes: 2 additions & 4 deletions animations/look_down.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
[
{"servo:pan:mvabs": 60},
{"servo:pan:mvabs": 50},
{"sleep": 0.5},
{"servo:neck:mvabs": 0},
{"sleep": 0.5},
{"servo:tilt:mvabs": 100},
{"servo:tilt:mvabs": 20},
{"sleep": 1}
]
4 changes: 2 additions & 2 deletions animations/look_up.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{"servo:neck:mvabs": 40},
{"servo:pan:mvabs": 50},
{"sleep": 0.5},
{"servo:tilt:mvabs": 0},
{"servo:tilt:mvabs": 80},
{"sleep": 1}
]
4 changes: 0 additions & 4 deletions animations/neck_forward.json

This file was deleted.

6 changes: 0 additions & 6 deletions animations/raised.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
[
{"servo:leg_l_hip:mvabs": 65},
{"servo:leg_r_hip:mvabs": 35},
{"servo:leg_l_knee:mvabs": 55},
{"servo:leg_r_knee:mvabs": 55},
{"servo:leg_l_ankle:mvabs": 65},
{"servo:leg_r_ankle:mvabs": 35},
{"sleep": 1}
]
6 changes: 0 additions & 6 deletions animations/sit.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
[
{"servo:leg_l_hip:mvabs": 80},
{"servo:leg_r_hip:mvabs": 20},
{"servo:leg_l_knee:mvabs": 5},
{"servo:leg_r_knee:mvabs": 100},
{"servo:leg_l_ankle:mvabs": 35},
{"servo:leg_r_ankle:mvabs": 65},
{"sleep": 1}
]
5 changes: 2 additions & 3 deletions animations/sleep.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
[
{"servo:neck:mvabs": 85},
{"servo:tilt:mvabs": 55},
{"servo:pan:mvabs": 60},
{"servo:tilt:mvabs": 0},
{"servo:pan:mvabs": 90},
{"sleep": 1}
]
6 changes: 0 additions & 6 deletions animations/stand.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
[
{"servo:leg_l_ankle:mvabs": 60},
{"servo:leg_r_ankle:mvabs": 40},
{"servo:leg_l_knee:mvabs": 30},
{"servo:leg_r_knee:mvabs": 75},
{"servo:leg_l_hip:mvabs": 80},
{"servo:leg_r_hip:mvabs": 20},
{"sleep": 1}
]
6 changes: 0 additions & 6 deletions animations/tiptoes.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
[
{"servo:leg_l_hip:mvabs": 65},
{"servo:leg_r_hip:mvabs": 35},
{"servo:leg_l_knee:mvabs": 70},
{"servo:leg_r_knee:mvabs": 40},
{"servo:leg_l_ankle:mvabs": 80},
{"servo:leg_r_ankle:mvabs": 20},
{"sleep": 1}
]
5 changes: 2 additions & 3 deletions animations/wake.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
[
{"servo:neck:mvabs": 40},
{"servo:tilt:mvabs": 40},
{"servo:pan:mvabs": 60},
{"servo:tilt:mvabs": 50},
{"servo:pan:mvabs": 50},
{"sleep": 1}
]
2 changes: 1 addition & 1 deletion arduino_sketch/Order.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
enum Order {
HELLO = 0,
SERVO = 1,
MOTOR = 2,
SERVO_RELATIVE = 2,
ALREADY_CONNECTED = 3,
ERROR = 4,
RECEIVED = 5,
Expand Down
26 changes: 20 additions & 6 deletions arduino_sketch/ServoManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ ServoEasing ServoNP;

InverseKinematics ik;


class ServoManager
{
public:
void doInit()
{

// IMPORTANT: Communication from Pi uses index, these must be attached in the same order as they are referenced in the pi config
ServoLLH.attach(PIN_SLLH, PosStart[0]);
ServoLLK.attach(PIN_SLLK, PosStart[1]);
ServoLLA.attach(PIN_SLLA, PosStart[2]);
Expand Down Expand Up @@ -61,18 +62,31 @@ class ServoManager
continue;
}
if (Pos[tIndex] != -1)
moveSingleServo(tIndex, Pos[tIndex]);
moveSingleServo(tIndex, Pos[tIndex], false);
else
moveSingleServo(tIndex, moveRandom(tIndex)); // If scripted value is -1, generate random position based on range of currently indexed servo
moveSingleServo(tIndex, moveRandom(tIndex), false); // If scripted value is -1, generate random position based on range of currently indexed servo
}
//setEaseToForAllServosSynchronizeAndStartInterrupt(tSpeed);
}

// @todo just make this pass an array in to moveServos.
void moveSingleServo(uint8_t pServoIndex, int pPos)
void moveSingleServo(uint8_t pServoIndex, int pPos, boolean isRelative)
{
ServoEasing::ServoEasingNextPositionArray[pServoIndex] = pPos;
//setEaseToForAllServosSynchronizeAndStartInterrupt(tSpeed);
if (isRelative)
{
// Assuming pPos is a percentage, map to PosMin and PosMax and add to current position
int realChange = map(abs(pPos), 0, 100, PosMin[pServoIndex], PosMax[pServoIndex]);
if (pPos < 0)
{
realChange = -realChange;
}
ServoEasing::ServoEasingNextPositionArray[pServoIndex] = ServoEasing::ServoEasingNextPositionArray[pServoIndex] + realChange;
}
else
{
ServoEasing::ServoEasingNextPositionArray[pServoIndex] = pPos;
}
setEaseToForAllServosSynchronizeAndStartInterrupt(tSpeed);
}

void moveLegsAndStore(int x, int y, int *store)
Expand Down
5 changes: 4 additions & 1 deletion arduino_sketch/arduino_sketch.ino
Original file line number Diff line number Diff line change
Expand Up @@ -189,16 +189,19 @@ void getOrdersFromPi()
switch(order_received)
{
case SERVO:
case SERVO_RELATIVE:
{
int servo_identifier = PiConnect::read_i8();
int servo_angle = PiConnect::read_i16();
#ifdef DEBUG
PiConnect::write_order(SERVO);
PiConnect::write_i8(servo_identifier);
PiConnect::write_i16(servo_angle);
#endif
// sleep animations for 2 seconds to allow pi to control servos
setSleep(2000);
servoManager.moveSingleServo(servo_identifier - SERVO_PIN_OFFSET, servo_angle);
servoManager.moveSingleServo(servo_identifier, servo_angle, order_received == SERVO_RELATIVE);
// delay(2000);
break;
}
case PIN:
Expand Down
4 changes: 2 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ def main():
servos = dict()
for key in Config.servos:
s = Config.servos[key]
servos[key] = Servo(s['pin'], key, s['range'], start_pos=s['start'])
servos[key] = Servo(s['pin'], key, s['range'], s['id'], start_pos=s['start'])

# POWER
power = Power(Config.POWER_ENABLE_PIN)
# power = Power(Config.POWER_ENABLE_PIN)

led = LED(Config.LED_COUNT)
tts = TTS()
Expand Down
43 changes: 28 additions & 15 deletions modules/actuators/servo.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@

class Servo:

def __init__(self, pin, identifier, pwm_range, **kwargs):
def __init__(self, pin, identifier, pwm_range, index, **kwargs):
self.pin = pin
self.identifier = identifier
self.index = index
self.range = pwm_range
self.power = kwargs.get('power', True)

Expand All @@ -33,18 +34,25 @@ def __del__(self):
pass #self.reset()

def move_relative(self, percentage, safe=True):
new = self.pos + (self.translate(percentage) - self.range[0])
if new > self.range[1] and safe:
new = self.range[1]
elif new < self.range[0] and safe:
new = self.range[0]
if self.range[0] <= new <= self.range[1]:
this_move = self.calculate_move(self.pos, new)
self.execute_move(this_move)
self.pos = new
# Only calculate relative position if not using serial
# Otherwise it is done by the arduino
if not self.serial:
new = self.pos + (self.translate(percentage) - self.range[0])


if new > self.range[1] and safe:
new = self.range[1]
elif new < self.range[0] and safe:
new = self.range[0]
if self.range[0] <= new <= self.range[1]:
this_move = self.calculate_move(self.pos, new)
self.execute_move(this_move, True)
self.pos = new
else:
pub.sendMessage('log:error', '[Servo] Percentage %d out of range' % percentage)
raise ValueError('Percentage %d out of range' % percentage)
else:
pub.sendMessage('log:error', '[Servo] Percentage %d out of range' % percentage)
raise ValueError('Percentage %d out of range' % percentage)
self.execute_move([(percentage, 0)], True)

def move(self, percentage, safe=True):
if 0 <= percentage <= 100 or safe:
Expand All @@ -59,7 +67,7 @@ def move(self, percentage, safe=True):
pub.sendMessage('log:error', '[Servo] Percentage %d out of range' % percentage)
raise ValueError('Percentage %d out of range' % percentage)

def execute_move(self, sequence):
def execute_move(self, sequence, is_relative=False):
"""
Recursive function to handle each movement in sequence.
Move to first position then set thread.Timer for next movement after delay specified in movement 1.
Expand All @@ -77,8 +85,13 @@ def execute_move(self, sequence):
if self.power:
pub.sendMessage('power:use')
if self.serial:
# print(int(s[0]))
pub.sendMessage('serial', type=ArduinoSerial.DEVICE_SERVO, identifier=self.pin, message=s[0])
# just move the pan servo for now. Remove after debugging
if self.index != 7 and self.index != 6:
return;
type = ArduinoSerial.DEVICE_SERVO
if is_relative:
type = ArduinoSerial.DEVICE_SERVO_RELATIVE
pub.sendMessage('serial', type=type, identifier=self.index, message=s[0])
else:
self.pi.set_servo_pulsewidth(self.pin, s[0])
if len(sequence) > 1:
Expand Down
Loading

0 comments on commit c6b23fe

Please sign in to comment.