Homing OSL Joints¶
This tutorial demonstrates how to home the knee and ankle joints on the Open Source Leg (OSL) using the opensourceleg
Python library. You’ll learn how to initialize actuators and encoders, configure the robot platform, and use the built-in home()
method to calibrate the joints by driving them into physical stops and applying offsets.
Overview¶
This example shows how to:
- Initialize
DephyActuator
instances for the knee and ankle joints - Configure
AS5048B
magnetic absolute encoders via I2C - Instantiate the
OpenSourceLeg
platform with the defined components - Use the
home()
method to detect joint limits and assign calibrated offsets - Log joint and encoder positions to the terminal in real-time
Hardware Setup¶
- Actuators: Two Dephy Actuators are connected to
/dev/ttyACM0
and/dev/ttyACM1
. These control the knee and ankle respectively. - Encoders: Two AS5048B encoders are connected to I2C bus on the host controller.
For detailed setup instructions, refer to:
Software Setup¶
Ensure the opensourceleg
Python package is installed. Before running the full integration script, verify that each actuator and encoder is working individually. This helps isolate configuration issues.
Code Structure¶
The tutorial script is structured into seven key sections:
1. Configuration¶
from opensourceleg.actuators.base import CONTROL_MODES
from opensourceleg.actuators.dephy import DephyActuator
from opensourceleg.logging.logger import Logger
from opensourceleg.robots.osl import OpenSourceLeg
from opensourceleg.sensors.encoder import AS5048B
from opensourceleg.utilities import SoftRealtimeLoop
TIME_TO_STEP = 1.0
FREQUENCY = 200
DT = 1 / FREQUENCY
GEAR_RATIO = 9 * (83 / 18)
Key parameters:
FREQUENCY
: Control loop rate (200 Hz)DT
: Timestep per loop cycle, defined as1 / FREQUENCY
GEAR_RATIO
: Compound gear ratio applied to each joint (≈41.5:1)
2. Real-time loop and Logger¶
homing_logger = Logger(
log_path="./logs",
file_name="homing_joint",
)
clock = SoftRealtimeLoop(dt=DT)
This section:
- Initializes a
Logger
instance to write homing data to the./logs
directory - Starts a
SoftRealtimeLoop
for accurate timing
3. Actuator Initialization¶
actuators = {
"knee": DephyActuator(
tag="knee",
port="/dev/ttyACM0",
gear_ratio=GEAR_RATIO,
frequency=FREQUENCY,
dephy_log=False,
),
"ankle": DephyActuator(
tag="ankle",
port="/dev/ttyACM1",
gear_ratio=GEAR_RATIO,
frequency=FREQUENCY,
dephy_log=False,
This section:
- Instantiates two
DephyActuator
objects for the knee and ankle - Assigns ports, frequency, gear ratio, and disables internal logging
4. Sensor Initialization¶
sensors = {
"joint_encoder_knee": AS5048B(
tag="joint_encoder_knee",
bus=1,
A1_adr_pin=True,
A2_adr_pin=False,
zero_position=0,
enable_diagnostics=False,
),
"joint_encoder_ankle": AS5048B(
tag="joint_encoder_ankle",
bus=1,
A1_adr_pin=False,
A2_adr_pin=True,
zero_position=0,
enable_diagnostics=False,
This section:
- Instantiates two
AS5048B
encoders using the I2C interface - Each encoder is tagged and assigned its A1/A2 pin configuration
- Zero position is temporarily set to 0
5. Initialize OSL Platform¶
This section:
- Creates an instance of
OpenSourceLeg
and passes in the actuator and sensor dictionaries
6. Run Homing Routine¶
osl.home(
homing_voltage=2000,
homing_frequency=FREQUENCY,
homing_direction={"knee": -1, "ankle": -1},
output_position_offset={"knee": 0.0, "ankle": np.deg2rad(30.0)},
current_threshold=5000,
velocity_threshold=0.001,
This section:
- Calls
osl.home()
with user-defined voltages, direction, and thresholds - Each actuator rotates in a specified direction until one of the following is true:
- Velocity falls below
0.001 rad/s
- Current exceeds
5000 mA
- Once stopped, the motor is zeroed based on its position, and a calibrated offset is added (30° for ankle, 0° for knee)
7. Reset Torque and Start Logging¶
osl.knee.set_control_mode(CONTROL_MODES.CURRENT)
osl.knee.set_current_gains()
osl.ankle.set_control_mode(CONTROL_MODES.CURRENT)
osl.ankle.set_current_gains()
osl.knee.set_output_torque(0)
osl.ankle.set_output_torque(0)
# homing_logger.set_stream_terminator("\r")
for t in clock:
osl.update()
homing_logger.info(
This section:
- Switches both actuators to
CURRENT
control mode - Sets joint torques to 0 so they can be moved freely
- Logs the following information continuously:
- Elapsed time
- Output positions of the knee and ankle (in degrees)
- Raw encoder readings of the knee and ankle (in degrees)
Running the Script¶
-
Navigate to the tutorial directory:
-
Run the script:
-
Expected behavior:
- Both motors rotate slowly in a negative direction
- Movement stops once physical limits are detected (via current or velocity thresholds)
- Homing offsets are applied to calibrate the zero position
- Control mode switches to current control, torque is zeroed
- Joint and encoder positions print continuously in the terminal
Note: You can use Ctrl+C to terminate the loop at any time.