Skip to content

event-driven-robotics/omega_control

Repository files navigation

omega_control

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.

Table of Contents

Prerequisites

  • 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.

Installation

You can install omega-control in several ways:

Option 1: Install from PyPI (Recommended)

# 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

Option 2: Install from source

# 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 .

Option 3: Manual installation (Legacy)

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 matplotlib

Configure the SDK environment variables

Important: Regardless of the installation method, you must configure the Force Dimension SDK environment variables.

Linux Configuration

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 omega

Or 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.py

macOS Configuration

The 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 omega

Notes:

  • On macOS, DYLD_LIBRARY_PATH is 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.py

Quick Start

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.py

Usage Examples

This 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.

Basic Motion Control (motion_example.py)

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)

Trajectory Control (trajectory_example.py)

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()

Data Recording (data_recording_example.py)

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)

Force Preloading (preload_example.py)

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()

Running the Examples

To run any example:

python motion_example.py
python trajectory_example.py  
python data_recording_example.py
python preload_example.py

Each example will:

  1. Initialize the robot connection
  2. Perform the specified motion/control task
  3. Record position, velocity, and force data
  4. Save data to HDF5 format
  5. Generate plots showing the recorded data
  6. Safely close the robot connection

Troubleshooting

  • "Loader error" or OSError when importing:

    • Verify FORCEDIM_SDK points to the SDK root and DYLD_LIBRARY_PATH to the correct library directory for your platform (the lib/release/<platform> subfolder).
    • Ensure you installed the version of forcedimension-core compatible with your SDK.
  • Device count is 0:

    • Check USB connectivity and device power.
    • Confirm the device is supported by the SDK version you downloaded.

Authors

Maintainers:

Institution:
Istituto Italiano di Tecnologia (IIT)

Contributing

We welcome contributions! Please feel free to submit issues, feature requests, or pull requests.

For questions or support, please contact the maintainers above.

License

This project is licensed under the terms specified in the LICENSE file. Please refer to that file for detailed licensing information.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages