This guide covers the complete hardware setup process for integrating OpenControl with various robotic systems.
OpenControl supports a wide range of robotic hardware configurations, from single-arm setups to complex multi-robot systems. This guide provides step-by-step instructions for setting up your hardware components.
- Models: UR3, UR3e, UR5, UR5e, UR10, UR10e, UR16e
- Communication: Ethernet TCP/IP
- Control Frequency: Up to 500Hz
- Software: URScript, Real-Time Data Exchange (RTDE)
- Models: Panda, Research 3
- Communication: Ethernet (Franka Control Interface)
- Control Frequency: 1000Hz
- Software: libfranka, franka_ros
- Models: Gen2, Gen3, MOVO
- Communication: USB, Ethernet
- Control Frequency: 200Hz
- Software: Kinova API, kortex_driver
- Models: IRB series, YuMi
- Communication: Ethernet/IP, Robot Web Services
- Control Frequency: 250Hz
- Software: RobotStudio, ABB Robot Web Services
- Models: TurtleBot 2, 3, 4
- Base: Kobuki, Waffle, Waffle Pi
- Sensors: LiDAR, RGB-D camera, IMU
- Software: ROS/ROS2 navigation stack
- Models: Husky, Jackal, Ridgeback
- Communication: Ethernet, WiFi
- Sensors: GPS, IMU, cameras, LiDAR
- Software: ROS/ROS2 drivers
- Models: 2F-85, 2F-140, 3F series, Hand-E
- Communication: Modbus RTU, Ethernet/IP
- Force Control: Adaptive grasping
- Integration: Direct robot mounting
- Models: EGP, EGK, PGN series
- Communication: EtherCAT, Profinet
- Precision: High-precision positioning
- Integration: Tool changer compatible
- Intel RealSense: D435, D455, L515
- Microsoft Azure Kinect: DK
- Zed Cameras: Zed, Zed 2, Zed X
- Industrial Cameras: Basler, FLIR, IDS
- ATI: Nano, Mini, Gamma series
- Robotiq: FT 300, FT 150
- OnRobot: HEX series
- Weiss Robotics: KMS series
- SynTouch: BioTac sensors
- Shadow Robot: Tactile fingertips
- Digit: High-resolution tactile sensing
- GelSight: Vision-based tactile sensors
# Configure robot network interface
sudo ip addr add 192.168.1.10/24 dev eth0
sudo ip link set eth0 up
# Set up static routes (if needed)
sudo ip route add 192.168.1.0/24 via 192.168.1.1
# Configure firewall rules
sudo ufw allow from 192.168.1.0/24
sudo ufw allow out to 192.168.1.0/24Computer (192.168.1.10) ←→ Robot (192.168.1.100)
Computer (192.168.1.10)
↓
Switch (192.168.1.1)
├── Robot 1 (192.168.1.100)
├── Robot 2 (192.168.1.101)
└── Sensors (192.168.1.200+)
# Optimize network for real-time communication
sudo sysctl -w net.core.rmem_max=134217728
sudo sysctl -w net.core.wmem_max=134217728
sudo sysctl -w net.ipv4.tcp_rmem="4096 65536 134217728"
sudo sysctl -w net.ipv4.tcp_wmem="4096 65536 134217728"
# Disable network power management
sudo ethtool -s eth0 wol d- Power: Connect robot to appropriate power supply
- Network: Connect Ethernet cable to robot controller
- Emergency Stop: Connect external e-stop if required
- Tool: Mount gripper or tool with appropriate wiring
# Install UR drivers
sudo apt install ros-humble-ur-robot-driver
# Configure robot IP
export UR_ROBOT_IP=192.168.1.100
# Test connection
ping $UR_ROBOT_IP- Navigate to Installation → Network
- Set IP Address: 192.168.1.100
- Set Subnet Mask: 255.255.255.0
- Set Gateway: 192.168.1.1
- Enable Remote Control
# Safety limits configuration
safety_config = {
"joint_limits": {
"velocity": [3.14, 3.14, 3.14, 3.14, 3.14, 3.14], # rad/s
"acceleration": [15, 15, 15, 15, 15, 15] # rad/s²
},
"cartesian_limits": {
"velocity": 1.0, # m/s
"acceleration": 5.0, # m/s²
"force": 150.0 # N
},
"workspace": {
"x": [-0.8, 0.8],
"y": [-0.8, 0.8],
"z": [0.0, 1.2]
}
}- Power: Connect to Franka Control Unit
- Network: Connect computer directly to Franka Control Interface
- Emergency Stop: Connect shop floor e-stop
- Tool: Install tool with proper mounting and wiring
# Configure network for Franka
sudo ip addr add 172.16.0.1/16 dev eth0
sudo ip link set eth0 up
# Test Franka connection
ping 172.16.0.2 # Franka robot IP# Install libfranka
git clone --recursive https://github.com/frankaemika/libfranka.git
cd libfranka
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=OFF
make -j4
sudo make install
# Install franka_ros
sudo apt install ros-humble-franka-ros- Open Franka Desk in web browser:
https://172.16.0.2 - Activate FCI: Enable Franka Control Interface
- Set Collision Behavior: Configure collision thresholds
- Calibrate Tool: Set tool center point and mass properties
- Power: Connect to Kinova power adapter
- Communication: USB or Ethernet connection
- Tool: Mount gripper with Kinova interface
# Install Kinova API
wget https://artifactory.kinovaapps.com/artifactory/generic-public/cortex/API/2.6.0/kinova-api_2.6.0_amd64.deb
sudo dpkg -i kinova-api_2.6.0_amd64.deb
# Install ROS drivers
sudo apt install ros-humble-kinova-ros- Mounting: Secure camera to robot or fixed mount
- USB Connection: Use USB 3.0 for best performance
- Calibration: Ensure proper camera-to-robot calibration
# Install RealSense SDK
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE
sudo add-apt-repository "deb https://librealsense.intel.com/Debian/apt-repo $(lsb_release -cs) main"
sudo apt update
sudo apt install librealsense2-dkms librealsense2-utils librealsense2-dev
# Test camera
realsense-viewerfrom opencontrol.sensors import RealSenseCamera
camera = RealSenseCamera(
device_id=0,
width=640,
height=480,
fps=30,
enable_color=True,
enable_depth=True,
enable_infrared=False,
depth_units=0.001, # mm to m conversion
clipping_distance=3.0 # meters
)# Install ATI drivers
# Download from ATI website and follow installation instructions
# Configure network interface
sudo ip addr add 192.168.1.10/24 dev eth0from opencontrol.sensors import ATIForceTorqueSensor
ft_sensor = ATIForceTorqueSensor(
ip_address="192.168.1.101",
calibration_file="FT12345.cal",
sample_rate=1000, # Hz
filter_frequency=50 # Hz
)from opencontrol.sensors import RobotiqFT300
ft_sensor = RobotiqFT300(
device="/dev/ttyUSB0", # or IP address for network version
baud_rate=115200,
timeout=1.0
)- Mounting: Attach to robot flange using adapter plate
- Wiring: Connect power and communication cables
- Tool Center Point: Configure TCP in robot software
from opencontrol.grippers import Robotiq2F85
gripper = Robotiq2F85(
device="/dev/ttyUSB0", # or Modbus TCP IP
baud_rate=115200,
stroke=85, # mm
force_limit=235 # N
)
# Initialize and test
gripper.connect()
gripper.activate()
gripper.open()
gripper.close()- Mounting: Use standard ISO flange
- Communication: EtherCAT or Profinet connection
- Safety: Configure safety functions
from opencontrol.grippers import SchunkEGP
gripper = SchunkEGP(
ip_address="192.168.1.102",
stroke=64, # mm
force_limit=140 # N
)from opencontrol.calibration import HandEyeCalibration
# Collect calibration data
calibrator = HandEyeCalibration(
robot=robot,
camera=camera,
calibration_target="checkerboard",
target_size=(9, 6),
square_size=0.025 # meters
)
# Collect calibration poses
poses = []
for i in range(20):
# Move robot to calibration pose
robot.move_to_pose(calibration_poses[i])
# Capture image and detect target
image = camera.get_frame().color_image
pose_data = calibrator.detect_target(image)
if pose_data is not None:
poses.append({
"robot_pose": robot.get_pose(),
"target_pose": pose_data
})
# Perform calibration
transformation = calibrator.calibrate(poses)
camera.set_extrinsics(transformation)from opencontrol.calibration import ForceSensorCalibration
# Initialize calibration
ft_calibrator = ForceSensorCalibration(
force_sensor=ft_sensor,
robot=robot
)
# Remove bias (no external forces)
ft_calibrator.remove_bias()
# Gravity compensation
tool_mass = 0.5 # kg
tool_com = [0.0, 0.0, 0.1] # meters from sensor frame
ft_calibrator.set_tool_parameters(
mass=tool_mass,
center_of_mass=tool_com
)from opencontrol.safety import EmergencyStopMonitor
# Configure emergency stop monitoring
estop_monitor = EmergencyStopMonitor(
estop_pin=18, # GPIO pin
robot=robot,
sensors=[camera, ft_sensor],
safe_stop_mode="category_1" # IEC 60204-1
)
estop_monitor.start_monitoring()from opencontrol.safety import SafetyMonitor
safety_monitor = SafetyMonitor(
robot=robot,
limits={
"workspace": {
"x": [-0.8, 0.8],
"y": [-0.8, 0.8],
"z": [0.0, 1.2]
},
"velocity": 0.5, # m/s
"acceleration": 2.0, # m/s²
"force": 50.0, # N
"torque": 10.0 # Nm
}
)from opencontrol.safety import VisionCollisionDetector
collision_detector = VisionCollisionDetector(
camera=camera,
robot=robot,
safety_distance=0.1, # meters
detection_frequency=30 # Hz
)
# Monitor for collisions
while robot.is_moving():
if collision_detector.check_collision():
robot.emergency_stop()
break- Stable Surface: Use vibration-damped table
- Robot Mounting: Secure robot base with appropriate bolts
- Cable Management: Route cables safely away from robot motion
- Lighting: Ensure adequate and consistent lighting for vision
- Physical Barriers: Install safety fencing if required
- Light Curtains: For collaborative applications
- Safety Mats: Pressure-sensitive floor mats
- Warning Signs: Appropriate safety signage
from opencontrol.workspace import WorkspaceManager
# Define workspace zones
workspace = WorkspaceManager()
# Safe zone for normal operation
workspace.add_zone(
name="safe_zone",
bounds={
"x": [-0.6, 0.6],
"y": [-0.6, 0.6],
"z": [0.1, 0.8]
},
max_velocity=0.5
)
# Restricted zone near humans
workspace.add_zone(
name="collaborative_zone",
bounds={
"x": [0.2, 0.6],
"y": [-0.2, 0.2],
"z": [0.1, 0.5]
},
max_velocity=0.1,
force_limit=25.0
)
# Forbidden zone
workspace.add_zone(
name="forbidden_zone",
bounds={
"x": [-0.8, -0.6],
"y": [-0.8, 0.8],
"z": [0.0, 1.2]
},
access="forbidden"
)def test_hardware_connectivity():
"""Test all hardware connections."""
results = {}
# Test robot connection
try:
robot.connect()
robot.get_joint_positions()
results["robot"] = "PASS"
except Exception as e:
results["robot"] = f"FAIL: {e}"
# Test camera
try:
camera.start()
frame = camera.get_frame()
results["camera"] = "PASS"
except Exception as e:
results["camera"] = f"FAIL: {e}"
# Test force sensor
try:
ft_sensor.start()
reading = ft_sensor.get_reading()
results["force_sensor"] = "PASS"
except Exception as e:
results["force_sensor"] = f"FAIL: {e}"
return resultsdef test_robot_motion():
"""Test robot motion capabilities."""
# Joint space motion test
home_joints = [0, -1.57, 0, -1.57, 0, 0, 0]
robot.move_to_joints(home_joints)
# Cartesian motion test
poses = [
Pose([0.4, 0.2, 0.3], [0, 1, 0, 0]),
Pose([0.4, 0.0, 0.3], [0, 1, 0, 0]),
Pose([0.4, -0.2, 0.3], [0, 1, 0, 0])
]
for pose in poses:
robot.move_to_pose(pose)
time.sleep(1.0)def validate_calibration():
"""Validate hand-eye calibration accuracy."""
# Known target positions
target_positions = [
[0.4, 0.2, 0.1],
[0.4, 0.0, 0.1],
[0.4, -0.2, 0.1]
]
errors = []
for target_pos in target_positions:
# Move robot to look at target
robot.move_to_pose(Pose(target_pos + [0, 0, 0.2], [0, 1, 0, 0]))
# Detect target in camera
image = camera.get_frame().color_image
detected_pos = detect_target_position(image)
# Calculate error
error = np.linalg.norm(np.array(target_pos) - np.array(detected_pos))
errors.append(error)
mean_error = np.mean(errors)
print(f"Mean calibration error: {mean_error:.3f} m")
return mean_error < 0.005 # 5mm tolerance# Check network connectivity
ping <robot_ip>
# Check robot status
# For UR robots:
# - Check teach pendant for errors
# - Verify remote control is enabled
# - Check safety system status
# For Franka robots:
# - Check Franka Desk for errors
# - Verify FCI is activated
# - Check collision detection status# Camera problems
lsusb # Check USB connection
v4l2-ctl --list-devices # List video devices
# Force sensor problems
dmesg | grep tty # Check serial connections
netstat -an | grep <port> # Check network connections# Diagnostics for Robotiq grippers
gripper.get_status() # Check gripper status
gripper.reset() # Reset gripper
gripper.activate() # Reactivate gripper# Install real-time kernel
sudo apt install linux-lowlatency
# Configure CPU governor
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
# Set process priorities
sudo chrt -f 80 python robot_control.py# Optimize network buffers
sudo sysctl -w net.core.rmem_max=134217728
sudo sysctl -w net.core.wmem_max=134217728
# Disable network interrupt coalescing
sudo ethtool -C eth0 rx-usecs 0 tx-usecs 0- Verify robot emergency stop functionality
- Check cable connections and routing
- Test basic robot motions
- Verify sensor readings
- Clean camera lenses and sensors
- Check robot calibration accuracy
- Verify safety system functionality
- Update system logs
- Perform full system calibration
- Update robot firmware if needed
- Check mechanical wear and tear
- Review safety procedures
# Automated health monitoring
def monitor_robot_health():
"""Monitor robot health metrics."""
health_data = {
"joint_temperatures": robot.get_joint_temperatures(),
"motor_currents": robot.get_motor_currents(),
"error_log": robot.get_error_log(),
"runtime_hours": robot.get_runtime_hours()
}
# Check for anomalies
for joint, temp in enumerate(health_data["joint_temperatures"]):
if temp > 70: # Celsius
logger.warning(f"Joint {joint} temperature high: {temp}°C")
return health_dataAfter completing hardware setup:
- System Integration: Test complete system integration
- Calibration: Perform comprehensive calibration procedures
- Safety Validation: Validate all safety systems
- Performance Testing: Measure system performance metrics
- Documentation: Document your specific hardware configuration
- [Robot Manufacturer Documentation]
- Sensor Calibration Guide
- Safety Systems Guide
- Troubleshooting Guide
Author: Nik Jois (nikjois@llamasearch.ai)
Last Updated: December 2024