Python framework for controlling Force Dimension OmegaX haptic devices
A comprehensive Python framework for controlling Force Dimension OmegaX haptic devices. This package provides high-level abstractions for device initialization, motion control, trajectory generation, force feedback, and real-time data recording.
- macOS (ARM or Intel) or Linux with a supported Python 3.10 installation (we recommend using Conda to manage the environment).
- Force Dimension SDK downloaded and extracted (example path:
~/SDKs/ForceDimension/sdk-3.17.6). - A Conda distribution (miniconda or anaconda) or another virtual environment manager.
If you don't already have the SDK, get it from Force Dimension (https://www.forcedimension.com/software/sdk) and place it under ~/SDKs/ForceDimension/ or another location you control.
You can install omega-control in several ways:
# Create and activate a conda environment
conda create -n omega python=3.10 pip -y
conda activate omega
# Install omega-control and its dependencies
pip install omega-control# Clone the repository
git clone https://github.com/event-driven-robotics/omega_control.git
cd omega_control
# Create and activate environment
conda create -n omega python=3.10 pip -y
conda activate omega
# Install in development mode
pip install -e .
# Or install normally
pip install .If you prefer the original manual setup:
conda create -n omega python=3.10 pip -y
conda activate omega
python -m pip install --upgrade pip
python -m pip install forcedimension-core h5py numpy matplotlibImportant: Regardless of the installation method, you must configure the Force Dimension SDK environment variables.
For Linux systems, use LD_LIBRARY_PATH instead of DYLD_LIBRARY_PATH:
conda env config vars set \
FORCEDIM_SDK="$HOME/SDKs/ForceDimension/sdk-3.17.6" \
LD_LIBRARY_PATH="$FORCEDIM_SDK/lib/release/linux-x86_64-gcc"
conda deactivate
conda activate omegaOr export them temporarily:
export FORCEDIM_SDK="$HOME/SDKs/ForceDimension/sdk-3.17.6"
export LD_LIBRARY_PATH="$FORCEDIM_SDK/lib/release/linux-x86_64-gcc"
python your_script.pyThe Force Dimension SDK provides native libraries that must be discoverable by the dynamic loader. We set environment variables attached to the Conda environment so they are persistent whenever the environment is activated.
Adjust FORCEDIM_SDK to the SDK path you have on disk. For example:
conda env config vars set \
FORCEDIM_SDK="$HOME/SDKs/ForceDimension/sdk-3.17.6" \
DYLD_LIBRARY_PATH="$FORCEDIM_SDK/lib/release/mac-arm64-clang"
conda deactivate
conda activate omegaNotes:
- On macOS,
DYLD_LIBRARY_PATHis used by the dynamic loader. Recent macOS versions can restrict use of DYLD variables for system processes; however, for user-space Python launched from your terminal this approach usually works. - If you prefer not to modify environment variables globally, you can export them in the shell before running your script:
export FORCEDIM_SDK="$HOME/SDKs/ForceDimension/sdk-3.17.6"
export DYLD_LIBRARY_PATH="$FORCEDIM_SDK/lib/release/mac-arm64-clang"
python your_script.pyRun a small Python snippet while the omega environment is active to verify the SDK
loads and the device is visible:
import forcedimension_core.dhd as dhd
try:
print("SDK version:", dhd.getSDKVersion())
print("Device count:", dhd.getDeviceCount())
except OSError as e:
print("Loader error:", e)
# If device count > 0 you can proceed to use the higher-level utilities in this repo.Run this by saving it in a file (e.g. test_sdk.py) and running:
python test_sdk.pyThis repository includes several example scripts demonstrating different capabilities of the OmegaX control framework. All examples use the OmegaRobot class which provides a high-level interface to the Force Dimension SDK.
Simple point-to-point movements along each axis with data recording:
from omega_control import OmegaRobot
robot = OmegaRobot(verbose=False)
robot.to_origin()
robot.start_recording(freq=1000) # Record at 1 kHz
# Move along each axis and return to origin
robot.set_pos([0.05, 0.0, 0.0]) # Move 5cm along X
robot.to_origin()
robot.set_pos([0.0, 0.05, 0.0]) # Move 5cm along Y
robot.to_origin()
robot.set_pos([0.0, 0.0, 0.05]) # Move 5cm along Z
robot.to_origin()
robot.stop_recording()
filename = robot.save_log(filename="axis_finding")
robot.close()
# Visualize the recorded data
robot.plot_log(filename=filename)Continuous sinusoidal motion with real-time trajectory tracking:
import math
import time
from omega_control import OmegaRobot
# Parameters
amplitude = 0.03 # 3 cm amplitude
frequency = 0.25 # 0.25 Hz (4 second period)
duration = 5.0 # Run for 5 seconds
robot = OmegaRobot(verbose=False)
robot.to_origin()
robot.start_recording(freq=1000)
# Generate smooth trajectory
t0 = time.time()
while (time.time() - t0) < duration:
t = time.time() - t0
x = amplitude * math.sin(2 * math.pi * frequency * t)
y = 1.5 * amplitude * math.sin(2 * math.pi * frequency * t)
z = 0.5 * amplitude * math.sin(2 * math.pi * frequency * t)
robot.set_pos([x, y, z], tracking=True) # Continuous tracking
time.sleep(0.001) # ~1 kHz control loop
robot.stop_recording()
robot.save_log(filename="trajectory")
robot.close()High-frequency data collection of position, velocity, and force:
import time
from omega_control import OmegaRobot
robot = OmegaRobot(verbose=True)
robot.to_origin()
# Record at high frequency
robot.start_recording(freq=10000) # 10 kHz sampling
time.sleep(2) # Collect for 2 seconds
robot.stop_recording()
# Save and visualize data
filename = robot.save_log()
robot.close()
robot.plot_log(filename=filename)Apply controlled force along an axis using adaptive positioning:
from omega_control import OmegaRobot
robot = OmegaRobot(verbose=True)
robot.to_origin()
# Move to starting position
robot.set_pos([0.0, 0.0, -0.052])
robot.start_recording(freq=1000)
# Apply 1N downward force along Z-axis
robot.preload(target_axis="z", target_force=-1.0)
robot.stop_recording()
robot.save_log(filename="preload_data")
robot.close()To run any example:
python motion_example.py
python trajectory_example.py
python data_recording_example.py
python preload_example.pyEach example will:
- Initialize the robot connection
- Perform the specified motion/control task
- Record position, velocity, and force data
- Save data to HDF5 format
- Generate plots showing the recorded data
- Safely close the robot connection
-
"Loader error" or
OSErrorwhen importing:- Verify
FORCEDIM_SDKpoints to the SDK root andDYLD_LIBRARY_PATHto the correct library directory for your platform (thelib/release/<platform>subfolder). - Ensure you installed the version of
forcedimension-corecompatible with your SDK.
- Verify
-
Device count is 0:
- Check USB connectivity and device power.
- Confirm the device is supported by the SDK version you downloaded.
Maintainers:
- Simon Mueller-Cleve (@smullercleve)
- Quentin Halbach (@qhalbach)
Institution:
Istituto Italiano di Tecnologia (IIT)
We welcome contributions! Please feel free to submit issues, feature requests, or pull requests.
For questions or support, please contact the maintainers above.
This project is licensed under the terms specified in the LICENSE file. Please refer to that file for detailed licensing information.