The HALs folder contains all Hardware Abstraction Layer (HAL) implementations for the UCSC Slugbotics robotic arm project. A HAL provides a unified interface for controlling different types of robotic arm hardware (real or simulated), abstracting away the hardware-specific details and exposing a consistent API to the rest of the software stack.
A Hardware Abstraction Layer (HAL) is a software component that allows the main control code to interact with different hardware platforms (e.g., physical arms, simulators, remote arms) using the same set of methods. This enables rapid switching between hardware backends for development, testing, and deployment.
All HALs inherit from HAL_base, which defines the required interface for arm control, camera access, and gripper manipulation.
-
HAL_base.py
The abstract base class for all HALs. Defines the required interface for joint control, camera access, gripper operations, and joint limits. -
sim_HAL.py
HAL for the CoppeliaSim robotic arm simulator, using the ZeroMQ Remote API. Allows simulation-based development and testing. -
physical_HAL.py
HAL for the physical robotic arm hardware, using the Adafruit ServoKit, stepper drivers, and PiCamera2 for camera input. -
laptop_test_HAL.py
HAL for development and testing on a laptop using a standard webcam. No joint control; only provides camera frames. -
remote_HAL.py
HAL for controlling a remote robotic arm via HTTP API (using FastAPI). Bridges to a remote server running the arm. -
logan_hal/
Contains hardware-specific drivers and helpers for the Logan arm design, such as stepper and gripper drivers.
-
Select the HAL
In your main application or controller, instantiate the desired HAL class. For example:from HALs.sim_HAL import sim_HAL hal = sim_HAL(host="127.0.0.1") hal.start_arm()
-
Use the Unified API
All HALs provide the same methods for joint control, camera access, and gripper operation:set_joint(joint_index, joint_angle)get_joint(joint_index)joint_count()get_arm_cam_img_rgb()get_camera_focal_length()gripper_open()gripper_close()start_arm()stop_arm()
-
Switching HALs
To switch hardware backends, simply change which HAL class you instantiate. The rest of your code should not need to change.
-
Inherit from HAL_base
Create a new Python file in theHALsdirectory (or a subdirectory) and define a class that inherits fromHAL_base. -
Implement Required Methods
Implement all abstract methods fromHAL_base, including:start_arm,stop_armset_joint,get_joint,joint_countget_arm_cam_img_rgb,get_camera_focal_lengthgripper_open,gripper_close
-
Handle Joint Limits
Use the joint limit methods (set_joint_min,set_joint_max, etc.) to enforce hardware safety. -
Thread Safety
If your HAL interacts with hardware or external APIs, use locks to ensure thread safety. -
Test Your HAL
Test your HAL implementation with the main application and controllers to ensure compatibility.
from HALs.HAL_base import HAL_base
class MyCustomHAL(HAL_base):
def __init__(self):
super().__init__()
# Initialize hardware here
def start_arm(self) -> bool:
# Initialize hardware
return True
def stop_arm(self) -> bool:
# Cleanup hardware
return True
def set_joint(self, joint_index, joint_angle) -> bool:
# Set joint position
return True
def get_joint(self, joint_index) -> float:
# Get joint position
return 0.0
def joint_count(self) -> int:
return 3
def get_arm_cam_img_rgb(self):
# Return camera frame as RGB numpy array
pass
def get_camera_focal_length(self) -> float:
# Return camera focal length in pixels
return 800.0
def gripper_open(self) -> bool:
# Open gripper
return True
def gripper_close(self) -> bool:
# Close gripper
return TrueFor more details, see the docstrings in HAL_base.py and the example implementations in this folder.