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), Linux, or Windows with a supported Python 3.10 installation.
- A virtual environment named
omegaor another environment manager of your choice. - Force Dimension SDK downloaded and extracted, for example
~/SDKs/ForceDimension/sdk-3.17.6.
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 virtual environment
python3 -m venv omega
source omega/bin/activate
# 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
python3 -m venv omega
source omega/bin/activate
# Install in development mode
pip install -e .
# Or install normally
pip install .If you prefer the original manual setup:
python3 -m venv omega
source omega/bin/activate
python -m pip install --upgrade pip
python -m pip install forcedimension-core h5py numpy matplotlibImportant: The package auto-detects the SDK root in common locations and accepts both
FDSDK and FORCEDIM_SDK. If your SDK is installed somewhere unusual, point either variable
at the SDK root before importing the package. The omega-control-doctor command below can
confirm what the package sees after installation.
omega-control-doctorIf you use virtualenvwrapper, source the helper after workon omega instead of exporting
variables by hand each time:
source /path/to/omega_control/omega_control/scripts/omega_env.sh "$HOME/SDKs/ForceDimension/sdk-3.17.6"You can also add that line to your virtualenv's postactivate hook and omega_env_deactivate
to the matching postdeactivate hook if you want the setup and cleanup to happen automatically.
For Linux systems, set the SDK root and, if needed, the native library path inside the active
shell session for omega:
export FORCEDIM_SDK="$HOME/SDKs/ForceDimension/sdk-3.17.6"
export FDSDK="$FORCEDIM_SDK"
export LD_LIBRARY_PATH="$FORCEDIM_SDK/lib/release/linux-x86_64-gcc"If you use a shell activation script, you can add the same exports there so they load whenever
omega is activated.
If import errors persist, run omega-control-doctor and verify that the reported SDK root matches
the one on disk.
Finally, ensure you can find the Omega robot using:
lsusb
THe output should look like this:
Bus 001 Device 006: ID 1451:0402 Force Dimension omega.x haptic device
1451: Vendor Vendor: Product
Now we must add a udev rule. To do so run:
sudo nano /etc/udev/rules.d/99-forcedimension.rules
and add
SUBSYSTEM=="usb", ATTR{idVendor}=="1451", ATTR{idProduct}=="0401", GROUP="plugdev", MODE="0660"
The Force Dimension SDK provides native libraries that must be discoverable by the
dynamic loader. Set the environment variables in the active omega shell session or in
that environment's activation script so they are restored automatically.
Adjust FORCEDIM_SDK to the SDK path you have on disk. For example:
export FORCEDIM_SDK="$HOME/SDKs/ForceDimension/sdk-3.17.6"
export FDSDK="$FORCEDIM_SDK"
export DYLD_LIBRARY_PATH="$FORCEDIM_SDK/lib/release/mac-arm64-clang"Notes:
- 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 FDSDK="$FORCEDIM_SDK"
export DYLD_LIBRARY_PATH="$FORCEDIM_SDK/lib/release/mac-arm64-clang"
python your_script.pyIf you are on Intel macOS, the SDK may use the mac-x86_64-clang library directory instead.
On Windows, activate your omega environment and set FDSDK to the SDK root after installing
the Force Dimension SDK. The package will try to resolve the SDK root from that environment
variable, and omega-control-doctor can confirm what it sees.
$env:Path = "C:\SDKs\ForceDimension\sdk-3.17.6\bin;$env:Path"
$env:FDSDK = "C:\SDKs\ForceDimension\sdk-3.17.6"
python -m pip install omega-control
omega-control-doctorIf the import still fails on Windows, check that the SDK's native DLLs are available to your shell session before launching Python.
Run 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
FDSDKorFORCEDIM_SDKpoints to the SDK root andLD_LIBRARY_PATH/DYLD_LIBRARY_PATHpoints to the correct library directory for your platform (thelib/release/<platform>subfolder). - On Windows, verify
FDSDKpoints to the SDK root and that the SDK DLLs are visible to the current shell session. - 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.