cleaning up

This commit is contained in:
apirrone 2025-03-17 11:39:29 +01:00
parent 1bc8ba2d1f
commit cdfb571479
24 changed files with 9 additions and 2855 deletions

View file

@ -21,3 +21,12 @@ class FeetContacts:
if GPIO.input(RIGHT_FOOT_PIN) == GPIO.LOW:
right = True
return np.array([left, right])
if __name__ == "__main__":
import time
feet_contacts = FeetContacts()
while True:
print(feet_contacts.get())
time.sleep(0.05)

File diff suppressed because it is too large Load diff

View file

@ -1,120 +0,0 @@
from pypot.feetech import FeetechSTS3215IO
import time
import numpy as np
from threading import Thread
class FeetechPWMControl:
def __init__(self, ids, init_pos_rad, usb_port="/dev/ttyACM0"):
self.io = FeetechSTS3215IO(
usb_port,
baudrate=1000000,
use_sync_read=True,
)
self.ids = ids
self.io.set_mode({id: 2 for id in self.ids})
self.kps = np.ones(len(self.ids)) * 32 # default kp
self.init_pos_rad = init_pos_rad
self.init_pos_deg = np.rad2deg(self.init_pos_rad)
self.control_freq = 200 # Hz
self.goal_positions = [0] * len(self.ids)
self.goal_positions = self.init_pos_deg
self.present_positions = [0] * len(self.ids)
self.last_positions = [0] * len(self.ids)
self.present_speeds = [0] * len(self.ids)
self.speed_decimation = 2
self.speed_decimation_index = 0
self.last_t = time.time()
Thread(target=self.update, daemon=True).start()
def set_kps(self, kps):
self.kps = np.array(kps)
def disable_torque(self):
self.io.set_mode({id: 0 for id in self.ids})
self.io.disable_torque(self.ids)
# def enable_torque(self):
# self.io.enable_torque(self.ids)
# self.io.set_mode({id: 2 for id in self.ids})
def freeze(self):
present_position = list(self.io.get_present_position(self.ids))
print(present_position)
self.io.set_goal_position(
{id: present_position[i] for i, id in enumerate(self.ids)}
)
self.io.set_mode({id: 0 for id in self.ids})
self.io.enable_torque(self.ids)
def update(self):
while True:
s = time.time()
try:
self.present_positions = self.io.get_present_position(self.ids)
# self.present_speeds = self.io.get_present_speed(self.ids)
except Exception as e:
print(e)
continue
if len(self.present_positions) != len(self.ids):
print("ERROR : present_positions and ids do not have the same length")
time.sleep(1 / self.control_freq)
continue
errors = np.array(self.goal_positions) - np.array(self.present_positions)
pwms = self.kps * errors
pwms = np.int16(pwms)
pwms = np.clip(pwms, -1000, 1000)
pwm_magnitudes = abs(pwms)
direction_bits = [1 if pwm >= 0 else 0 for pwm in pwms]
goal_times = [
(direction_bits[i] << 10) | pwm_magnitudes[i]
for i in range(len(pwm_magnitudes))
]
try:
self.io.set_goal_time({id: goal_times[i] for i, id in enumerate(self.ids)})
except Exception as e:
print(e)
continue
if self.speed_decimation_index % self.speed_decimation == 0:
self.present_speeds = (
np.array(self.present_positions) - np.array(self.last_positions)
) / (time.time() - self.last_t)
self.last_positions = np.array(self.present_positions).copy()
self.last_t = time.time()
took = time.time() - s
# print("Took : ", np.around(took, 3), ". Budget : ", np.around(1/self.control_freq, 3), "diff : ", ((1/self.control_freq - took)))
# if (1 / self.control_freq - took) < 0:
# print(
# "Low level control budget exceded by ",
# np.around(took - 1 / self.control_freq, 3),
# )
time.sleep(max(0, (1 / self.control_freq - took)))
self.speed_decimation_index += 1
if __name__ == "__main__":
ids = [1, 2]
pwm_control = FeetechPWMControl(ids)
pwm_control.enable_torque()
pwm_control.set_kps([32, 32])
pwm_control.goal_positions = [-90, -90]
try:
while True:
pwm_control.goal_positions = [90, 90]
time.sleep(1)
pwm_control.goal_positions = [-90, -90]
time.sleep(1)
except KeyboardInterrupt:
pwm_control.disable_torque()

View file

@ -1,111 +0,0 @@
import rustypot
import time
import numpy as np
from threading import Thread
class FeetechPWMControl:
def __init__(self, ids, init_pos_rad, usb_port="/dev/ttyACM0"):
self.io = rustypot.feetech(usb_port, 1000000)
self.ids = ids
self.io.set_mode(self.ids, 2)
self.kps = np.ones(len(self.ids)) * 32 # default kp
self.init_pos_rad = init_pos_rad
self.init_pos_deg = np.rad2deg(self.init_pos_rad)
self.control_freq = 100 # Hz
self.goal_positions = [0] * len(self.ids)
self.goal_positions = self.init_pos_deg
self.present_positions = [0] * len(self.ids)
self.last_positions = [0] * len(self.ids)
self.present_speeds = [0] * len(self.ids)
self.speed_decimation = 2
self.speed_decimation_index = 0
self.last_t = time.time()
Thread(target=self.update, daemon=True).start()
def set_kps(self, kps):
self.kps = np.array(kps)
def disable_torque(self):
self.io.set_mode(self.ids, 0)
self.io.disable_torque(self.ids)
def freeze(self):
present_position = list(self.io.read_present_position(self.ids))
self.io.write_goal_position(self.ids, present_position)
self.io.set_mode(self.ids, 0)
def update(self):
while True:
s = time.time()
try:
self.present_positions = np.rad2deg(self.io.read_present_position(self.ids))
# self.present_speeds = self.io.get_present_speed(self.ids)
except Exception as e:
print(e)
continue
if len(self.present_positions) != len(self.ids):
print("ERROR : present_positions and ids do not have the same length")
time.sleep(1 / self.control_freq)
continue
errors = np.array(self.goal_positions) - np.array(self.present_positions)
pwms = self.kps * errors
pwms = np.int16(pwms)
pwms = np.clip(pwms, -1000, 1000)
pwm_magnitudes = abs(pwms)
direction_bits = [1 if pwm >= 0 else 0 for pwm in pwms]
goal_times = [
(direction_bits[i] << 10) | pwm_magnitudes[i]
for i in range(len(pwm_magnitudes))
]
try:
self.io.set_goal_time(self.ids, goal_times)
# self.io.set_goal_time({id: goal_times[i] for i, id in enumerate(self.ids)})
except Exception as e:
print(e)
continue
if self.speed_decimation_index % self.speed_decimation == 0:
self.present_speeds = (
np.array(self.present_positions) - np.array(self.last_positions)
) / (time.time() - self.last_t)
self.last_positions = np.array(self.present_positions).copy()
self.last_t = time.time()
took = time.time() - s
# print("Took : ", np.around(took, 3), ". Budget : ", np.around(1/self.control_freq, 3), "diff : ", ((1/self.control_freq - took)))
if (1 / self.control_freq - took) < 0:
print(
"Low level control budget exceded by ",
np.around(took - 1 / self.control_freq, 3),
)
time.sleep(max(0, (1 / self.control_freq - took)))
self.speed_decimation_index += 1
if __name__ == "__main__":
ids = [1, 2]
pwm_control = FeetechPWMControl(ids)
pwm_control.enable_torque()
pwm_control.set_kps([32, 32])
pwm_control.goal_positions = [-90, -90]
try:
while True:
pwm_control.goal_positions = [90, 90]
time.sleep(1)
pwm_control.goal_positions = [-90, -90]
time.sleep(1)
except KeyboardInterrupt:
pwm_control.disable_torque()

View file

@ -1,188 +0,0 @@
import time
from typing import List
import numpy as np
from mini_bdx_runtime.io_330 import Dxl330IO
class HWI:
def __init__(self, usb_port="/dev/ttyUSB1", baudrate=3000000):
self.dxl_io = Dxl330IO(usb_port, baudrate=baudrate, use_sync_read=True)
self.joints = {
"right_hip_yaw": 10,
"right_hip_roll": 11,
"right_hip_pitch": 12,
"right_knee": 13,
"right_ankle": 14,
"left_hip_yaw": 20,
"left_hip_roll": 21,
"left_hip_pitch": 22,
"left_knee": 23,
"left_ankle": 24,
"neck_pitch": 30,
"head_pitch": 31,
"head_yaw": 32,
}
self.init_pos = {
"right_hip_yaw": 0.001171696610228082,
"right_hip_roll": 0.006726989242258406,
"right_hip_pitch": 1.0129772861831692,
"right_knee": -1.4829304760981399,
"right_ankle": 0.6444901047812701,
"left_hip_yaw": -0.002853397830292128,
"left_hip_roll": 0.01626303761810685,
"left_hip_pitch": 1.0105624704499077,
"left_knee": -1.4865015965817336,
"left_ankle": 0.6504953719748071,
"neck_pitch": -0.17453292519943295,
"head_pitch": -0.17453292519943295,
"head_yaw": 0,
"left_antenna": 0,
"right_antenna": 0,
}
# self.joints_offsets = {
# "right_hip_yaw": -0.02,
# "right_hip_roll": 0,
# "right_hip_pitch": 0,
# "right_knee": -0.05,
# "right_ankle": -0.1,
# "left_hip_yaw": -0.05,
# "left_hip_roll": 0.05,
# "left_hip_pitch": 0.02,
# "left_knee": -0.08,
# "left_ankle": -0.1,
# "neck_pitch": 0,
# "head_pitch": 0.3,
# "head_yaw": 0,
# # "left_antenna": 0,
# # "right_antenna": 0,
# }
self.joints_offsets = {
"right_hip_yaw": 0.0,
"right_hip_roll": 0,
"right_hip_pitch": 0,
"right_knee": 0.0,
"right_ankle": 0.0,
"left_hip_yaw": 0.00,
"left_hip_roll": 0.00,
"left_hip_pitch": 0.00,
"left_knee": 0.00,
"left_ankle": 0.0,
"neck_pitch": 0,
"head_pitch": 0.0,
"head_yaw": 0,
# "left_antenna": 0,
# "right_antenna": 0,
}
self.init_pos = {
joint: position - offset
for joint, position, offset in zip(
self.init_pos.keys(),
self.init_pos.values(),
self.joints_offsets.values(),
)
}
# current based position : 0x5
self.dxl_io.set_operating_mode({id: 0x3 for id in self.joints.values()})
def set_pid(self, pid, joint_name):
self.dxl_io.set_pid_gain({self.joints[joint_name]: pid})
def set_pid_all(self, pid):
self.dxl_io.set_pid_gain({id: pid for id in self.joints.values()})
def set_low_torque(self):
self.dxl_io.set_pid_gain({id: [100, 0, 0] for id in self.joints.values()})
def set_high_torque(self):
# https://emanual.robotis.com/docs/en/dxl/x/xl330-m288/#position-pid-gain80-82-84-feedforward-1st2nd-gains88-90
# 128 P factor
# 16 D factor
self.dxl_io.set_pid_gain(
{id: [10 * 128, 0, int(0.5 * 16)] for id in self.joints.values()}
)
for name in ["neck_pitch", "head_pitch", "head_yaw"]:
self.dxl_io.set_pid_gain({self.joints[name]: [150, 0, 0]})
def turn_on(self):
# self.set_low_torque()
self.dxl_io.enable_torque(self.joints.values())
time.sleep(1)
# self.goto_zero()
self.set_position_all(self.init_pos)
time.sleep(1)
# self.set_high_torque()
def turn_off(self):
self.dxl_io.disable_torque(self.joints.values())
def goto_zero(self):
goal_dict = {joint: 0 for joint in self.joints.keys()}
self.set_position_all(goal_dict)
def set_position_all(self, joints_positions):
"""
joints_positions is a dictionary with joint names as keys and joint positions as values
Warning: expects radians
"""
ids_positions = {
self.joints[joint]: np.rad2deg(-position)
for joint, position in joints_positions.items()
}
# print(ids_positions)
self.dxl_io.set_goal_position(ids_positions)
def set_position(self, joint_name, position):
self.dxl_io.set_goal_position({self.joints[joint_name]: np.rad2deg(-position)})
def get_present_current(self, joint_name):
return self.dxl_io.get_present_current([self.joints[joint_name]])[0]
def get_voltage_all(self):
return self.dxl_io.get_present_input_voltage(self.joints.values())
def get_present_input_voltage(self, joint_name):
return self.dxl_io.get_present_input_voltage([self.joints[joint_name]])[0]
def get_current_all(self):
return self.dxl_io.get_present_current(self.joints.values())
def get_goal_current(self, joint_name):
return self.dxl_io.get_goal_current([self.joints[joint_name]])[0]
def get_current_limit(self, joint_name):
return self.dxl_io.get_current_limit([self.joints[joint_name]])[0]
def get_present_positions(self):
present_position = list(
np.around(
np.deg2rad((self.dxl_io.get_present_position(self.joints.values()))), 3
)
)
factor = np.ones(len(present_position)) * -1
return present_position * factor
def get_present_velocities(self, rad_s=True) -> List[float]:
"""
Returns the present velocities in rad/s or rev/min
"""
# rev/min
present_velocities = np.array(
self.dxl_io.get_present_velocity(self.joints.values())
)
if rad_s:
present_velocities = (2 * np.pi * present_velocities) / 60 # rad/s
factor = np.ones(len(present_velocities)) * -1
return list(present_velocities * factor)
def get_operating_modes(self):
return self.dxl_io.get_operating_mode(self.joints.values())

View file

@ -1,207 +0,0 @@
import time
from typing import List
import numpy as np
# from pypot.feetech import FeetechSTS3215IO
# from mini_bdx_runtime.feetech_pwm_control import FeetechPWMControl
from mini_bdx_runtime.feetech_pwm_control_rustypot import FeetechPWMControl
class HWI:
def __init__(self, usb_port="/dev/ttyACM0"):
# Order matters here
self.joints = {
"left_hip_yaw": 20,
"left_hip_roll": 21,
"left_hip_pitch": 22,
"left_knee": 23,
"left_ankle": 24,
"neck_pitch": 30,
"head_pitch": 31,
"head_yaw": 32,
"head_roll": 33,
# "left_antenna": None,
# "right_antenna": None,
"right_hip_yaw": 10,
"right_hip_roll": 11,
"right_hip_pitch": 12,
"right_knee": 13,
"right_ankle": 14,
}
self.zero_pos = {
"left_hip_yaw": 0,
"left_hip_roll": 0,
"left_hip_pitch": 0,
"left_knee": 0,
"left_ankle": 0,
"neck_pitch": 0,
"head_pitch": 0,
"head_yaw": 0,
"head_roll": 0,
# "left_antenna":0,
# "right_antenna":0,
"right_hip_yaw": 0,
"right_hip_roll": 0,
"right_hip_pitch": 0,
"right_knee": 0,
"right_ankle": 0,
}
self.init_pos = {
"left_hip_yaw": 0.002,
"left_hip_roll": 0.053,
"left_hip_pitch": -0.63,
"left_knee": 1.368,
"left_ankle": -0.784,
"neck_pitch": 0.0,
"head_pitch": 0.0,
"head_yaw": 0,
"head_roll": 0,
# "left_antenna": 0,
# "right_antenna": 0,
"right_hip_yaw": -0.003,
"right_hip_roll": -0.065,
"right_hip_pitch": 0.635,
"right_knee": 1.379,
"right_ankle": -0.796,
}
# self.init_pos = self.zero_pos # TODO REMOVE
# self.joints_offsets = {
# "left_hip_yaw": 0.07,
# "left_hip_roll": -0.1,
# "left_hip_pitch": 0.0,
# "left_knee": 0.05,
# "left_ankle": -0.1,
# "neck_pitch": 0.1,
# "head_pitch": 0.1,
# "head_yaw": 0,
# "head_roll": 0.1,
# # "left_antenna": 0,
# # "right_antenna": 0,
# "right_hip_yaw": -0.15,
# "right_hip_roll": 0.15,
# "right_hip_pitch": 0.05,
# "right_knee": -0.05,
# "right_ankle": -0.08,
# }
self.joints_offsets = {
"left_hip_yaw" : 0.084,
"left_hip_roll" : -0.112,
"left_hip_pitch" : -0.024,
"left_knee" : 0.005,
"left_ankle" : -0.09,
"neck_pitch" : 0.017,
"head_pitch" : 0.114,
"head_yaw" : -0.083,
"head_roll" : 0.072,
# "left_antenna": 0,
# "right_antenna": 0,
"right_hip_yaw" : -0.13499999999999998,
"right_hip_roll" : 0.205,
"right_hip_pitch" : 0.064,
"right_knee" : -0.027999999999999997,
"right_ankle" : -0.09799999999999999,
}
init_pos_with_offsets = {
joint: pos + self.joints_offsets[joint]
for joint, pos in self.init_pos.items()
}
self.control = FeetechPWMControl(
ids=list(self.joints.values()),
init_pos_rad=list(init_pos_with_offsets.values()),
usb_port=usb_port,
)
self.kps = np.ones(len(self.joints)) * 32 # default kp
self.low_torque_kps = np.ones(len(self.joints)) * 8 # default kp
def set_kps(self, kps):
self.kps = kps
self.control.set_kps(self.kps)
def turn_on(self):
self.control.set_kps(self.low_torque_kps)
print("turn on : low KPS set")
time.sleep(1)
self.set_position_all(self.init_pos)
print("turn on : init pos set")
time.sleep(1)
self.control.set_kps(self.kps)
print("turn on : high kps")
def turn_off(self):
self.control.disable_torque()
def freeze(self):
self.control.freeze()
def set_position_all(self, joints_positions):
"""
joints_positions is a dictionary with joint names as keys and joint positions as values
Warning: expects radians
"""
ids_positions = {
self.joints[joint]: np.rad2deg(position + self.joints_offsets[joint])
for joint, position in joints_positions.items()
}
self.control.goal_positions = list(ids_positions.values())
def get_present_positions(self, ignore=[]):
"""
Returns the present positions in radians
"""
# present_positions = np.deg2rad(
# self.control.io.get_present_position(self.joints.values())
# )
present_positions = np.deg2rad(self.control.present_positions)
present_positions = [
pos - self.joints_offsets[joint]
for joint, pos in zip(self.joints.keys(), present_positions)
if joint not in ignore
]
return np.array(np.around(present_positions, 3))
def get_present_velocities(self, rad_s=True, ignore=[]):
"""
Returns the present velocities in rad/s (default) or rev/min
"""
# deg/s
present_velocities = np.array(self.control.present_speeds)
present_velocities = [
vel for joint, vel in zip(self.joints.keys(), present_velocities) if joint not in ignore
]
# present_velocities = np.array(
# self.control.io.get_present_speed(self.joints.values())
# )
if rad_s:
present_velocities = np.deg2rad(present_velocities) # rad/s
return np.array(np.around(present_velocities, 3))
def get_present_voltages(self):
return np.array(self.control.io.get_present_voltage(self.joints.values())) * 0.1
# def get_present_velocities(self, rad_s=True):
# """
# Returns the present velocities in rad/s (default) or rev/min
# """
# # rev/min
# present_velocities = np.array(
# self.control.io.get_present_speed(self.joints.values())
# )
# if rad_s:
# present_velocities = (2 * np.pi * present_velocities) / 60 # rad/s
# return np.array(np.around(present_velocities, 3))

View file

@ -1,180 +0,0 @@
import time
from typing import List
import numpy as np
from pypot.feetech import FeetechSTS3215IO
class HWI:
def __init__(self, usb_port="/dev/ttyACM0", baudrate=3000000):
self.dxl_io = FeetechSTS3215IO(
usb_port,
baudrate=1000000,
use_sync_read=True,
)
self.joints = {
"left_hip_yaw": 20,
"left_hip_roll": 21,
"left_hip_pitch": 22,
"left_knee": 23,
"left_ankle": 24,
"neck_pitch": 30,
"head_pitch": 31,
"head_yaw": 32,
"head_roll": 33,
# "left_antenna": None,
# "right_antenna": None,
"right_hip_yaw": 10,
"right_hip_roll": 11,
"right_hip_pitch": 12,
"right_knee": 13,
"right_ankle": 14,
}
self.zero_pos = {
"left_hip_yaw": 0,
"left_hip_roll": 0,
"left_hip_pitch": 0,
"left_knee": 0,
"left_ankle": 0,
"neck_pitch": 0,
"head_pitch": 0,
"head_yaw": 0,
"head_roll": 0,
# "left_antenna":0,
# "right_antenna":0,
"right_hip_yaw": 0,
"right_hip_roll": 0,
"right_hip_pitch": 0,
"right_knee": 0,
"right_ankle": 0,
}
self.init_pos = {
"left_hip_yaw": 0.002,
"left_hip_roll": 0.053,
"left_hip_pitch": -0.63,
"left_knee": 1.368,
"left_ankle": -0.784,
"neck_pitch": 0.002,
"head_pitch": 0.0,
"head_yaw": 0,
"head_roll": 0,
# "left_antenna": 0,
# "right_antenna": 0,
"right_hip_yaw": -0.003,
"right_hip_roll": -0.065,
"right_hip_pitch": 0.635,
"right_knee": 1.379,
"right_ankle": -0.796,
}
# self.init_pos = self.zero_pos # TODO REMOVE
self.joints_offsets = {
"left_hip_yaw": 0.07,
"left_hip_roll": -0.1,
"left_hip_pitch": 0.0,
"left_knee": 0.05,
"left_ankle": -0.1,
"neck_pitch": 0.1,
"head_pitch": 0.1,
"head_yaw": 0,
"head_roll": 0.1,
# "left_antenna": 0,
# "right_antenna": 0,
"right_hip_yaw": -0.15,
"right_hip_roll": 0.07,
"right_hip_pitch": 0.05,
"right_knee": -0.05,
"right_ankle": -0.08,
}
def set_pid(self, pid, joint_name):
# TODO
pass
def set_pid_all(self, pid):
# TODO WEIRD THINGS HERE
# If I set 32 manually, it works, but if it comes from a variable, it doesn't.
# sometimes i get : ValueError: byte must be in range(0, 256)
# sometimes 32 becomes 76 somehow
# P = np.uint8(pid[0])
# I = np.uint8(pid[1])
# D = np.uint8(pid[2])
self.dxl_io.set_P_coefficient({id: 32 for id in self.joints.values()})
self.dxl_io.set_I_coefficient({id: 0 for id in self.joints.values()})
self.dxl_io.set_D_coefficient({id: 32 for id in self.joints.values()})
def get_pid_all(self):
Ps = self.dxl_io.get_P_coefficient(self.joints.values())
Is = self.dxl_io.get_I_coefficient(self.joints.values())
Ds = self.dxl_io.get_D_coefficient(self.joints.values())
print("Ps", Ps)
print("Is", Is)
print("Ds", Ds)
return Ps, Is, Ds
def turn_on(self):
self.dxl_io.enable_torque(self.joints.values())
self.dxl_io.set_mode({id: 0 for id in self.joints.values()})
# self.dxl_io.set_mode
self.dxl_io.set_acceleration({id: 16 for id in self.joints.values()})
time.sleep(1)
self.set_position_all(self.init_pos)
time.sleep(1)
for name, id in self.joints.items():
if "neck" in name or "head" in name:
self.dxl_io.set_acceleration({id: 32})
else:
self.dxl_io.set_acceleration({id: 254})
def turn_off(self):
self.dxl_io.disable_torque(self.joints.values())
def set_position_all(self, joints_positions):
"""
joints_positions is a dictionary with joint names as keys and joint positions as values
Warning: expects radians
"""
ids_positions = {
self.joints[joint]: np.rad2deg(position + self.joints_offsets[joint])
for joint, position in joints_positions.items()
}
self.dxl_io.set_goal_position(ids_positions)
def set_position(self, joint_name, position):
self.dxl_io.set_goal_position({self.joints[joint_name]: np.rad2deg(-position)})
def get_present_positions(self):
"""
Returns the present positions in radians
"""
present_positions = np.deg2rad(
self.dxl_io.get_present_position(self.joints.values())
)
present_positions = [
pos - self.joints_offsets[joint]
for joint, pos in zip(self.joints.keys(), present_positions)
]
return np.array(np.around(present_positions, 3))
def get_present_velocities(self, rad_s=True):
"""
Returns the present velocities in rad/s (default) or rev/min
"""
# rev/min
present_velocities = np.array(
self.dxl_io.get_present_speed(self.joints.values())
)
if rad_s:
present_velocities = (2 * np.pi * present_velocities) / 60 # rad/s
return np.array(np.around(present_velocities, 3))

View file

@ -1,139 +0,0 @@
from mini_bdx_runtime.feetech import (
FeetechMotorsBus,
convert_radians_to_steps,
convert_steps_to_radians,
configure,
)
import time
import numpy as np
# Everything is in radians here
class HWI:
def __init__(self, usb_port="/dev/ttyACM0"):
self.motors = {
"right_hip_yaw": (10, "sts3215"),
"right_hip_roll": (11, "sts3215"),
"right_hip_pitch": (12, "sts3215"),
"right_knee": (13, "sts3215"),
"right_ankle": (14, "sts3215"),
"left_hip_yaw": (20, "sts3215"),
"left_hip_roll": (21, "sts3215"),
"left_hip_pitch": (22, "sts3215"),
"left_knee": (23, "sts3215"),
"left_ankle": (24, "sts3215"),
# "neck_pitch": (30, "sts3215"),
# "head_pitch": (31, "sts3215"),
# "head_yaw": (32, "sts3215"),
}
self.joints_offsets = {
"right_hip_yaw": 0.0,
"right_hip_roll": 0.0,
"right_hip_pitch": 0.0,
"right_knee": 0.0,
"right_ankle": 0.0,
"left_hip_yaw": 0.0,
"left_hip_roll": 0.0,
"left_hip_pitch": 0.0,
"left_knee": 0.0,
"left_ankle": 0.0,
# "neck_pitch": 0.0,
# "head_pitch": 0.0,
# "head_yaw": 0.0,
}
self.joints_sign = {
"right_hip_yaw": -1,
"right_hip_roll": -1,
"right_hip_pitch": 1,
"right_knee": -1,
"right_ankle": -1,
"left_hip_yaw": -1,
"left_hip_roll": -1,
"left_hip_pitch": 1,
"left_knee": -1,
"left_ankle": -1,
# "neck_pitch": -1,
# "head_pitch": -1,
# "head_yaw": -1,
}
self.init_pos = {
"right_hip_yaw": 0.001171696610228082,
"right_hip_roll": 0.006726989242258406,
"right_hip_pitch": 1.0129772861831692,
"right_knee": -1.4829304760981399,
"right_ankle": 0.6444901047812701,
"left_hip_yaw": -0.002853397830292128,
"left_hip_roll": 0.01626303761810685,
"left_hip_pitch": -1.0105624704499077,
"left_knee": -1.4865015965817336,
"left_ankle": 0.6504953719748071,
# "neck_pitch": -0.17453292519943295,
# "head_pitch": -0.17453292519943295,
# "head_yaw": 0,
}
self.zero_pos = {
"right_hip_yaw": 0,
"right_hip_roll": 0,
"right_hip_pitch": 0,
"right_knee": 0,
"right_ankle": 0,
"left_hip_yaw": 0,
"left_hip_roll": 0,
"left_hip_pitch": 0,
"left_knee": 0,
"left_ankle": 0,
# "neck_pitch": 0,
# "head_pitch": 0,
# "head_yaw": 0,
}
self.baudrate = 1000000
self.motors_bus = FeetechMotorsBus(port=usb_port, motors=self.motors)
self.motors_bus.connect()
configure(self.motors_bus)
# We add 180 to all dofs. They were mounted in a way that 180 degrees is the neutral position.
self.global_offset = np.deg2rad(180)
def enable_torque(self):
self.motors_bus.write("Torque_Enable", 1)
def disable_torque(self):
self.motors_bus.write("Torque_Enable", 0)
def turn_on(self):
self.enable_torque()
self.set_position_all(self.init_pos)
# self.set_position_all(self.zero_pos)
time.sleep(1)
def set_position_all(self, joints_positions: dict):
positions = np.array(list(joints_positions.values()))
signs = np.array(list(self.joints_sign.values()))
rads = positions * signs + self.global_offset
rads = list(rads)
steps = convert_radians_to_steps(rads, ["sts3215"])
self.motors_bus.write("Goal_Position", steps)
def get_position_all(self):
steps = self.motors_bus.read("Present_Position", self.motors)
rads = np.array(convert_steps_to_radians(steps, ["sts3215"]))
return rads - self.global_offset
# return rads * np.array(list(self.joints_sign.values()))# - self.global_offset
if __name__ == "__main__":
hwi = HWI()
hwi.turn_on()
# hwi.disable_torque()
# time.sleep(1)
# while True:
# print(hwi.get_position_all())
# time.sleep(0.1)

View file

@ -1,221 +0,0 @@
import pypot.dynamixel.conversion as conv
from pypot.dynamixel.io.abstract_io import AbstractDxlIO, _DxlAccess, _DxlControl
from pypot.dynamixel.protocol import v2 as v2
max_pos = 4096
max_deg = 360
max_current = 1750
def dxl_to_degree(value, model):
return round(((max_deg * float(value)) / (max_pos - 1)) - (max_deg / 2), 2)
def dxl_to_current(value, model):
if value > 0x7FFF:
value = value - 65536
return value
def current_to_dxl(value, model):
if value < 0:
value = value + 65536
return int(value)
def degree_to_dxl(value, model):
pos = int(round((max_pos - 1) * ((max_deg / 2 + float(value)) / max_deg), 0))
pos = min(max(pos, 0), max_pos - 1)
return pos
def dxl_to_velocity(value, model):
if value > 2 ** (4 * 8 - 1):
value = value - 2 ** (4 * 8)
return value * 0.229
class Dxl330IO(AbstractDxlIO):
_protocol = v2
controls = {
# EEPROM
"model": {
"address": 0x00,
"access": _DxlAccess.readonly,
"dxl_to_si": conv.dxl_to_model,
},
"firmware": {"address": 0x026, "length": 1, "access": _DxlAccess.readonly},
"id": {
"address": 0x07,
"length": 1,
"access": _DxlAccess.writeonly,
"setter_name": "change_id",
},
"baudrate": {
"address": 0x08,
"length": 1,
"access": _DxlAccess.writeonly,
"setter_name": "change_baudrate",
"si_to_dxl": conv.baudrate_to_dxl,
},
"return delay time": {
"address": 0x09,
"length": 1,
"dxl_to_si": conv.dxl_to_rdt,
"si_to_dxl": conv.rdt_to_dxl,
},
"angle limit": {
"address": 0x30,
"nb_elem": 2,
"dxl_to_si": lambda value, model: (
dxl_to_degree(value[0], model),
dxl_to_degree(value[1], model),
),
"si_to_dxl": lambda value, model: (
degree_to_dxl(value[0], model),
degree_to_dxl(value[1], model),
),
},
"control mode": {
"address": 0x10,
"length": 1,
"dxl_to_si": conv.dxl_to_control_mode,
"si_to_dxl": conv.control_mode_to_dxl,
},
"operating mode": {
"address": 0xB,
"length": 1,
},
"highest temperature limit": {
"address": 0x1F,
"length": 1,
"dxl_to_si": conv.dxl_to_temperature,
"si_to_dxl": conv.temperature_to_dxl,
},
"voltage limit": {
"address": 0x20,
"length": 1,
"nb_elem": 2,
"dxl_to_si": lambda value, model: (
conv.dxl_to_voltage(value[0], model),
conv.dxl_to_voltage(value[1], model),
),
"si_to_dxl": lambda value, model: (
conv.voltage_to_dxl(value[0], model),
conv.voltage_to_dxl(value[1], model),
),
},
"current limit": {
"address": 0x26,
"length": 2,
},
# RAM
"torque_enable": {
"address": 0x40,
"length": 1,
"dxl_to_si": conv.dxl_to_bool,
"si_to_dxl": conv.bool_to_dxl,
"getter_name": "is_torque_enabled",
"setter_name": "_set_torque_enable",
},
"LED": {
"address": 0x41,
"length": 1,
"dxl_to_si": conv.dxl_to_bool,
"si_to_dxl": conv.bool_to_dxl,
"setter_name": "_set_LED",
"getter_name": "is_led_on",
},
"LED color": {
"address": 0x19,
"length": 1,
"dxl_to_si": conv.dxl_to_led_color,
"si_to_dxl": conv.led_color_to_dxl,
},
"pid gain": {
"address": 0x50,
"length": 2,
"nb_elem": 3,
# "dxl_to_si": conv.dxl_to_pid,
# "si_to_dxl": conv.pid_to_dxl,
},
"goal position": {
"address": 0x74,
"length": 4,
"dxl_to_si": dxl_to_degree,
"si_to_dxl": degree_to_dxl,
},
"present velocity": {
"address": 0x80,
"length": 4,
"access": _DxlAccess.readonly,
"dxl_to_si": dxl_to_velocity,
},
"present position": {
"address": 0x84,
"length": 4,
"access": _DxlAccess.readonly,
"dxl_to_si": dxl_to_degree,
},
"present current": {
"address": 0x7E,
"length": 2,
"access": _DxlAccess.readonly,
"dxl_to_si": dxl_to_current,
},
"goal current": {
"address": 0x66,
"length": 2,
"dxl_to_si": dxl_to_current,
"si_to_dxl": current_to_dxl,
},
"present input voltage": {
"address": 0x90,
"length": 2,
"access": _DxlAccess.readonly,
"dxl_to_si": conv.dxl_to_voltage,
},
"present temperature": {
"address": 0x92,
"length": 1,
"access": _DxlAccess.readonly,
"dxl_to_si": conv.dxl_to_temperature,
},
}
def _add_control(
name,
address,
length=2,
nb_elem=1,
access=_DxlAccess.readwrite,
models=[
"XL-330",
],
dxl_to_si=lambda val, model: val,
si_to_dxl=lambda val, model: val,
getter_name=None,
setter_name=None,
):
control = _DxlControl(
name,
address,
length,
nb_elem,
access,
models,
dxl_to_si,
si_to_dxl,
getter_name,
setter_name,
)
Dxl330IO._generate_accessors(control)
for name, args in controls.items():
_add_control(name, **args)

View file

@ -1,214 +0,0 @@
import time
from typing import List
import numpy as np
# from pypot.feetech import FeetechSTS3215IO
# from mini_bdx_runtime.feetech_pwm_control import FeetechPWMControl
# from mini_bdx_runtime.feetech_pwm_control_rustypot import FeetechPWMControl
import rustypot
class HWI:
def __init__(self, usb_port="/dev/ttyACM0"):
# Order matters here
self.joints = {
"left_hip_yaw": 20,
"left_hip_roll": 21,
"left_hip_pitch": 22,
"left_knee": 23,
"left_ankle": 24,
"neck_pitch": 30,
"head_pitch": 31,
"head_yaw": 32,
"head_roll": 33,
# "left_antenna": None,
# "right_antenna": None,
"right_hip_yaw": 10,
"right_hip_roll": 11,
"right_hip_pitch": 12,
"right_knee": 13,
"right_ankle": 14,
}
self.zero_pos = {
"left_hip_yaw": 0,
"left_hip_roll": 0,
"left_hip_pitch": 0,
"left_knee": 0,
"left_ankle": 0,
"neck_pitch": 0,
"head_pitch": 0,
"head_yaw": 0,
"head_roll": 0,
# "left_antenna":0,
# "right_antenna":0,
"right_hip_yaw": 0,
"right_hip_roll": 0,
"right_hip_pitch": 0,
"right_knee": 0,
"right_ankle": 0,
}
self.init_pos = {
"left_hip_yaw": 0.002,
"left_hip_roll": 0.053,
"left_hip_pitch": -0.63,
"left_knee": 1.368,
"left_ankle": -0.784,
"neck_pitch": 0.0,
"head_pitch": 0.0,
"head_yaw": 0,
"head_roll": 0,
# "left_antenna": 0,
# "right_antenna": 0,
"right_hip_yaw": -0.003,
"right_hip_roll": -0.065,
"right_hip_pitch": 0.635,
"right_knee": 1.379,
"right_ankle": -0.796,
}
# self.init_pos = self.zero_pos # TODO REMOVE
# self.joints_offsets = {
# "left_hip_yaw": 0.07,
# "left_hip_roll": -0.1,
# "left_hip_pitch": 0.0,
# "left_knee": 0.05,
# "left_ankle": -0.1,
# "neck_pitch": 0.1,
# "head_pitch": 0.1,
# "head_yaw": 0,
# "head_roll": 0.1,
# # "left_antenna": 0,
# # "right_antenna": 0,
# "right_hip_yaw": -0.15,
# "right_hip_roll": 0.15,
# "right_hip_pitch": 0.05,
# "right_knee": -0.05,
# "right_ankle": -0.08,
# }
self.joints_offsets = {
"left_hip_yaw": 0.084,
"left_hip_roll": -0.112,
"left_hip_pitch": -0.024,
"left_knee": 0.005,
"left_ankle": -0.09,
"neck_pitch": 0.017,
"head_pitch": 0.114,
"head_yaw": -0.083,
"head_roll": 0.072,
# "left_antenna": 0,
# "right_antenna": 0,
"right_hip_yaw": -0.13499999999999998,
"right_hip_roll": 0.205,
"right_hip_pitch": 0.064,
"right_knee": -0.027999999999999997,
"right_ankle": -0.09799999999999999,
}
init_pos_with_offsets = {
joint: np.rad2deg(pos + self.joints_offsets[joint])
for joint, pos in self.init_pos.items()
}
# self.control = FeetechPWMControl(
# ids=list(self.joints.values()),
# init_pos_rad=list(init_pos_with_offsets.values()),
# usb_port=usb_port,
# )
self.kps = np.ones(len(self.joints)) * 32 # default kp
self.low_torque_kps = np.ones(len(self.joints)) * 8 # default kp
self.control = rustypot.FeetechController(
usb_port, 1000000, 100, list(self.joints.values()), list(self.kps), list(init_pos_with_offsets.values())
)
def set_kps(self, kps):
self.kps = kps
self.control.set_new_kps(self.kps)
def turn_on(self):
self.control.set_new_kps(self.low_torque_kps)
print("turn on : low KPS set")
time.sleep(1)
self.set_position_all(self.init_pos)
print("turn on : init pos set")
time.sleep(1)
self.control.set_new_kps(self.kps)
print("turn on : high kps")
def turn_off(self):
self.control.disable_torque()
def freeze(self):
self.control.freeze()
def set_position_all(self, joints_positions):
"""
joints_positions is a dictionary with joint names as keys and joint positions as values
Warning: expects radians
"""
ids_positions = {
self.joints[joint]: np.rad2deg(position + self.joints_offsets[joint])
for joint, position in joints_positions.items()
}
self.control.set_new_target(list(ids_positions.values()))
# self.control.goal_positions = list(ids_positions.values())
def get_present_positions(self, ignore=[]):
"""
Returns the present positions in radians
"""
# present_positions = np.deg2rad(
# self.control.io.get_present_position(self.joints.values())
# )
present_positions = np.deg2rad(self.control.get_present_position())
present_positions = [
pos - self.joints_offsets[joint]
for joint, pos in zip(self.joints.keys(), present_positions)
if joint not in ignore
]
return np.array(np.around(present_positions, 3))
def get_present_velocities(self, rad_s=True, ignore=[]):
"""
Returns the present velocities in rad/s (default) or rev/min
"""
# deg/s
present_velocities = np.array(self.control.get_current_speed())
present_velocities = [
vel
for joint, vel in zip(self.joints.keys(), present_velocities)
if joint not in ignore
]
# present_velocities = np.array(
# self.control.io.get_present_speed(self.joints.values())
# )
if rad_s:
present_velocities = np.deg2rad(present_velocities) # rad/s
return np.array(np.around(present_velocities, 3))
# def get_present_voltages(self):
# return np.array(self.control.io.get_present_voltage(self.joints.values())) * 0.1
# def get_present_velocities(self, rad_s=True):
# """
# Returns the present velocities in rad/s (default) or rev/min
# """
# # rev/min
# present_velocities = np.array(
# self.control.io.get_present_speed(self.joints.values())
# )
# if rad_s:
# present_velocities = (2 * np.pi * present_velocities) / 60 # rad/s
# return np.array(np.around(present_velocities, 3))

View file

@ -1,31 +0,0 @@
from pypot.feetech import FeetechSTS3215IO
io = FeetechSTS3215IO(
"/dev/ttyACM0",
baudrate=1000000,
use_sync_read=True,
)
joints = {
"left_hip_yaw": 20,
"left_hip_roll": 21,
"left_hip_pitch": 22,
"left_knee": 23,
"left_ankle": 24,
"neck_pitch": 30,
"head_pitch": 31,
"head_yaw": 32,
"head_roll": 33,
# "left_antenna": None,
# "right_antenna": None,
"right_hip_yaw": 10,
"right_hip_roll": 11,
"right_hip_pitch": 12,
"right_knee": 13,
"right_ankle": 14,
}
voltages = io.get_present_voltage(list(joints.values()))
for i, name in enumerate(joints.keys()):
print(name, round(voltages[i] * 0.1, 2), "V")

View file

@ -1,35 +0,0 @@
import numpy as np
import RPi.GPIO as GPIO
import time
# from time import sleep
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(12, GPIO.OUT)
pwm = GPIO.PWM(12, 50)
pwm.start(0) # Start the servo with 0 duty cycle ( at 0 deg position )
# pwm.ChangeDutyCycle(0)
# time.sleep(1)
# pwm.stop(0) # Stop the servo with 0 duty cycle ( at 0 deg position )
# GPIO.cleanup() # Clean up all the ports we've used.
start = time.time()
while True:
if time.time() - start > 3:
break
target_pwm = 10.0*np.sin(2*np.pi*1*time.time()) + 10
pwm.ChangeDutyCycle(target_pwm)
time.sleep(0.02)
# # Set up the PWM on pin #16 at 50Hz
# pwm.ChangeDutyCycle(5) # Tells the servo to turn to the left ( -90 deg position )
# sleep(0.5) # Tells the servo to Delay for 5sec
# pwm.ChangeDutyCycle(7.5) # Tells the servo to turn to the neutral position ( at 0 deg position )
# sleep(0.5) # Tells the servo to Delay for 5sec
# pwm.ChangeDutyCycle(10) # Tells the servo to turn to the right ( +90 deg position )
# sleep(0.5) # Tells the servo to Delay for 5sec
pwm.stop(0) # Stop the servo with 0 duty cycle ( at 0 deg position )
GPIO.cleanup() # Clean up all the ports we've used.

View file

@ -2,9 +2,6 @@
Sets up the robot in init position, you control the head with the xbox controller
"""
# from pypot.feetech import FeetechSTS3215IO
# from mini_bdx_runtime.hwi_feetech_pypot import HWI
from mini_bdx_runtime.rustypot_position_hwi import HWI
from mini_bdx_runtime.eyes import Eyes
import time

View file

@ -1,88 +0,0 @@
import socket
import time
import numpy as np
import pickle
from queue import Queue
from threading import Thread
from scipy.spatial.transform import Rotation as R
from FramesViewer.viewer import Viewer
from mini_bdx_runtime.rl_utils import quat_rotate_inverse
class IMUClient:
def __init__(self, host, port=1234, freq=30):
self.host = host
self.port = port
self.freq = freq
self.client_socket = socket.socket()
self.connected = False
while not self.connected:
try:
self.client_socket.connect((self.host, self.port))
self.connected = True
except Exception as e:
print(e)
time.sleep(0.5)
self.imu_queue = Queue(maxsize=1)
self.last_imu = [0, 0, 0, 0]
Thread(target=self.imu_worker, daemon=True).start()
def imu_worker(self):
while True:
try:
data = self.client_socket.recv(1024) # receive response
data = pickle.loads(data)
self.imu_queue.put(data)
except:
print("missed imu")
time.sleep(1 / self.freq)
def get_imu(self):
try:
self.last_imu = self.imu_queue.get(False)
except:
pass
return self.last_imu
if __name__ == "__main__":
client = IMUClient("192.168.248.253")
fv = Viewer()
fv.start()
pose = np.eye(4)
pose[:3, 3] = [0.1, 0.1, 0.1]
projected_gravities = []
try:
while True:
quat = client.get_imu()
try:
rot_mat = R.from_quat(quat).as_matrix()
pose[:3, :3] = rot_mat
fv.pushFrame(pose, "aze")
# euler = R.from_quat(quat).as_euler("xyz")
# euler[2] = 0
# quat = R.from_euler("xyz", euler).as_quat()
projected_gravity = quat_rotate_inverse(quat, [0, 0, -1])
projected_gravities.append(projected_gravity)
except Exception as e:
print("error", e)
pass
time.sleep(1 / 30)
except KeyboardInterrupt:
pass
# plot projected_gravities [[x, y, z], [x, y, z], ...]
# from matplotlib import pyplot as plt
# projected_gravities = np.array(projected_gravities)
# plt.plot(projected_gravities)
# plt.show()

View file

@ -1,62 +0,0 @@
import socket
import time
import pickle
from mini_bdx_runtime.raw_imu import Imu
from threading import Thread
import time
import argparse
class IMUServer:
def __init__(self, imu=None):
self.host = "0.0.0.0"
self.port = 1234
self.server_socket = socket.socket()
self.server_socket.setsockopt(
socket.SOL_SOCKET, socket.SO_REUSEADDR, 1
) # enable address reuse
self.server_socket.bind((self.host, self.port))
if imu is None:
self.imu = Imu(50, user_pitch_bias=args.pitch_bias)
else:
self.imu = imu
self.stop = False
Thread(target=self.run, daemon=True).start()
def run(self):
while not self.stop:
self.server_socket.listen(1)
conn, address = self.server_socket.accept() # accept new connection
print("Connection from: " + str(address))
try:
while True:
data = self.imu.get_data()
data = pickle.dumps(data)
conn.send(data) # send data to the client
time.sleep(1 / 30)
except:
pass
self.server_socket.close()
print("thread closed")
time.sleep(1)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--pitch_bias", type=float, default=0, help="deg")
args = parser.parse_args()
imu_server = IMUServer()
try:
while True:
time.sleep(0.01)
except KeyboardInterrupt:
print("Closing server")
imu_server.stop = True
time.sleep(2)

View file

@ -1,39 +0,0 @@
import RPi.GPIO as GPIO #Importe la bibliothèque pour contrôler les GPIOs
import numpy as np
import time
GPIO.setmode(GPIO.BCM) # Use physical pin numbering
# GPIO.setmode(GPIO.BOARD) #Définit le mode de numérotation (Board)
GPIO.setwarnings(False) #On désactive les messages d'alerte
LED = 24 #Définit le numéro du port GPIO qui alimente la led
GPIO.setup(LED, GPIO.OUT) #Active le contrôle du GPIO
# state = GPIO.input(LED) #Lit l'état actuel du GPIO, vrai si allumé, faux si éteint
GPIO.output(LED, GPIO.HIGH) #On l'allume
clignottement_time = 0.1
cli_s = time.time()
low = False
while True:
if not low and np.random.rand() > 0.99:
print("cli")
GPIO.output(LED, GPIO.LOW)
cli_s = time.time()
low = True
if time.time() - cli_s > clignottement_time:
GPIO.output(LED, GPIO.HIGH)
low = False
time.sleep(0.01)
# if state : #Si GPIO allumé
# GPIO.output(LED, GPIO.LOW) #On léteint
# else : #Sinon
# GPIO.output(LED, GPIO.HIGH) #On l'allume

View file

@ -1,14 +0,0 @@
import pickle
imu_data = pickle.load(open("imu_data.pkl", "rb"))
gyros = imu_data["gyros"]
acceleros = imu_data["accels"]
import matplotlib.pyplot as plt
plt.plot(gyros)
plt.show()
plt.plot(acceleros)
plt.show()

View file

@ -1,62 +0,0 @@
import RPi.GPIO as GPIO
import time
class ServoController:
def __init__(self, pin1, pin2):
self.pin1 = pin1
self.pin2 = pin2
GPIO.setmode(GPIO.BCM)
GPIO.setup(self.pin1, GPIO.OUT)
GPIO.setup(self.pin2, GPIO.OUT)
# Create PWM objects for both servos (50Hz frequency)
self.pwm1 = GPIO.PWM(self.pin1, 50)
self.pwm2 = GPIO.PWM(self.pin2, 50)
self.pwm1.start(0)
self.pwm2.start(0)
def map_input_to_angle(self, value):
"""
Maps an input range of [-1, 1] to an angle range of [0°, 180°].
"""
return 90 + (value * 90) # Maps -1 to 0°, 0 to 90°, and 1 to 180°
def set_position(self, servo, value):
"""
Moves the servo based on an input value in the range [-1, 1].
:param servo: 1 for the first servo, 2 for the second servo
:param value: A float between -1 and 1
"""
if -1 <= value <= 1:
angle = self.map_input_to_angle(value)
duty = 2 + (angle / 18) # Convert angle to duty cycle (1ms-2ms)
if servo == 1:
self.pwm1.ChangeDutyCycle(duty)
elif servo == 2:
self.pwm2.ChangeDutyCycle(duty)
else:
print("Invalid servo number!")
# time.sleep(0.3) # Allow time for movement
else:
print("Invalid input! Enter a value between -1 and 1.")
def stop(self):
"""Stops PWM and cleans up GPIO."""
self.pwm1.stop()
self.pwm2.stop()
GPIO.cleanup()
# Initialize the ServoController for GPIO12 and GPIO13
servo_control = ServoController(pin1=12, pin2=13)
try:
while True:
servo_num = int(input("Enter servo number (1 or 2): "))
value = float(input("Enter position (-1 to 1): "))
servo_control.set_position(servo_num, value)
except KeyboardInterrupt:
print("Stopping servos...")
servo_control.stop()

View file

@ -1,75 +0,0 @@
''' pg_midi_sound101.py
play midi music files (also mp3 files) using pygame
tested with Python273/331 and pygame192 by vegaseat
'''
#code modified by James DeVito from here: https://www.daniweb.com/programming/software-development/code/454835/let-pygame-play-your-midi-or-mp3-files
import sys
import pygame as pg
import os
import time
def play_music(music_file):
'''
stream music with mixer.music module in blocking manner
this will stream the sound from disk while playing
'''
clock = pg.time.Clock()
try:
pg.mixer.music.load(music_file)
print("Music file {} loaded!".format(music_file))
except pygame.error:
print("File {} not found! {}".format(music_file, pg.get_error()))
return
pg.mixer.music.play()
# If you want to fade in the audio...
# for x in range(0,100):
# pg.mixer.music.set_volume(float(x)/100.0)
# time.sleep(.0075)
# # check if playback has finished
while pg.mixer.music.get_busy():
clock.tick(30)
freq = 44100 # audio CD quality
bitsize = -16 # unsigned 16 bit
channels = 1 # 1 is mono, 2 is stereo
buffer = 2048 # number of samples (experiment to get right sound)
pg.mixer.init(freq, bitsize, channels, buffer)
if len(sys.argv) > 1:
try:
user_volume = float(sys.argv[1])
except ValueError:
print("Volume argument invalid. Please use a float (0.0 - 1.0)")
pg.mixer.music.fadeout(1000)
pg.mixer.music.stop()
raise SystemExit
print("Playing at volume: " + str(user_volume)+ "\n")
pg.mixer.music.set_volume(user_volume)
mp3s = []
for file in os.listdir("."):
if file.endswith(".wav"):
mp3s.append(file)
print(mp3s)
for x in mp3s:
try:
play_music(x)
time.sleep(.25)
except KeyboardInterrupt:
# if user hits Ctrl/C then exit
# (works only in console mode)
pg.mixer.music.fadeout(1000)
pg.mixer.music.stop()
raise SystemExit
else:
print("Please specify volume as a float! (0.0 - 1.0)")

View file

@ -1,15 +0,0 @@
import RPi.GPIO as GPIO
LEFT_FOOT_PIN = 22
RIGHT_FOOT_PIN = 27
GPIO.setwarnings(False) # Ignore warning for now
GPIO.setmode(GPIO.BCM) # Use physical pin numbering
GPIO.setup(LEFT_FOOT_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(RIGHT_FOOT_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
while True: # Run forever
print("=")
if GPIO.input(LEFT_FOOT_PIN) == GPIO.LOW:
print("LEFT!")
if GPIO.input(RIGHT_FOOT_PIN) == GPIO.LOW:
print("RIGHT! ")

View file

@ -1,7 +0,0 @@
from mini_bdx_runtime.xbox_controller import XBoxController
import time
xbox = XBoxController(50)
while True:
print(xbox.get_last_command())
time.sleep(0.1)

View file

@ -1,4 +1,3 @@
# from mini_bdx_runtime.hwi_feetech_pypot import HWI
from mini_bdx_runtime.rustypot_control_hwi import HWI
hwi = HWI()

View file

@ -1,4 +1,3 @@
# from mini_bdx_runtime.hwi_feetech_pypot import HWI
from mini_bdx_runtime.rustypot_position_hwi import HWI
import time

View file

@ -1,11 +1,8 @@
import time
import pickle
# import pygame
import numpy as np
# from mini_bdx_runtime.hwi_feetech_pwm_control import HWI
# from mini_bdx_runtime.rustypot_control_hwi import HWI
from mini_bdx_runtime.rustypot_position_hwi import HWI
from mini_bdx_runtime.onnx_infer import OnnxInfer
from mini_bdx_runtime.rl_utils import make_action_dict, LowPassActionFilter