A comprehensive, type-safe Python interface for OmniPreSense radar sensors
Project description
OmniPreSense Radar
A comprehensive, type-safe Python interface for OmniPreSense radar sensors
Supports all OPS241/OPS242/OPS243 radar models with full API coverage
⚠️ DISCLAIMER: This is an unofficial, community-developed library. The author is not affiliated with OmniPreSense Corp. This library provides a Python interface for OmniPreSense radar sensors but is not endorsed or supported by the company.
🚀 Quick Start • 📚 Examples • 🛠️ Troubleshooting • 🤝 Contributing
✨ Features
- 📋 Complete API Coverage - All commands from the official API documentation
- 🔒 Type-Safe - Full typing support with comprehensive enums and data classes
- 📡 Multiple Sensor Support - Doppler (-A), FMCW (-B), and combined (-C) sensor types
- 🧵 Thread-Safe - Robust serial communication with proper synchronization
- 🔧 Context Managers - Automatic resource cleanup with
withstatements - 📊 Rich Data Structures - Structured radar readings with timestamps and metadata
- ⚡ High Performance - Efficient data streaming with configurable callbacks
- 🛡️ Error Handling - Comprehensive exception hierarchy with detailed messages
📡 Supported Models
| Model | Type | Features | Detection Range | Max Speed |
|---|---|---|---|---|
| OPS241-A | Doppler | Motion, Speed, Direction, Magnitude | 20-25m | 31.1 m/s |
| OPS242-A | Doppler | Enhanced sensitivity | 20-25m | 31.1 m/s |
| OPS243-A | Doppler | Advanced + Range* | 75-100m | 31.1 m/s |
| OPS241-B | FMCW | Range, Magnitude | 15-20m | N/A |
| OPS243-C | Combined | All features | 50-60m | 31.1 m/s |
*Range measurement pending in firmware
🚀 Quick Start
Installation
pip install omnipresense
Basic Usage
from omnipresense import create_radar, Units, OutputMode
import time
# Create radar sensor
radar = create_radar('OPS243-C', '/dev/ttyACM0')
# Use context manager for automatic cleanup
with radar:
# Configure sensor
radar.set_units(Units.KILOMETERS_PER_HOUR)
# Enable output modes (required for data transmission)
radar.enable_output_mode(OutputMode.SPEED, True)
radar.enable_output_mode(OutputMode.DIRECTION, True)
radar.enable_output_mode(OutputMode.MAGNITUDE, True)
# Define callback for radar data
def on_detection(reading):
if reading.speed and reading.speed > 1.0:
direction = reading.direction.value if reading.direction else "?"
distance = f", Distance: {reading.range_m:.1f}m" if reading.range_m else ""
print(f"Speed: {reading.speed:.1f} km/h, Direction: {direction}{distance}")
# Start streaming data
print("Move something in front of the radar...")
radar.start_streaming(on_detection)
time.sleep(10) # Stream for 10 seconds
Important: Always enable appropriate output modes (
OutputMode.SPEED,OutputMode.DIRECTION,OutputMode.MAGNITUDE_SPEED) for data transmission. Without these, the radar will not send any data.
📋 Requirements
- Python: 3.8.1+
- Dependencies:
pyserial>= 3.4
📁 Examples
The examples/ directory contains working scripts for different use cases:
basic_usage.py- Simple km/h speed detection with distancebasic_usage_raw.py- PySerial version showing raw protocolsimple_doppler.py- Doppler radar with direction detectionsimple_range.py- FMCW range measurementcombined_example.py- OPS243-C combined featuresdebug_usage.py- Comprehensive debugging toolraw_data_test.py- Raw data inspection utilitybaudrate_troubleshooting_example.py- UART/baudrate configuration and troubleshootingcosine_correction_example.py- Cosine error correction for angled installationswater_height_averaging_example.py- Water level monitoring with averagingvehicle_speed_averaging_example.py- Vehicle/traffic speed monitoring
Run any example:
python examples/basic_usage.py
⚙️ Key Configuration
Output Modes (Required)
# Enable data transmission (essential!)
radar.enable_output_mode(OutputMode.SPEED, True)
radar.enable_output_mode(OutputMode.DIRECTION, True)
radar.enable_output_mode(OutputMode.MAGNITUDE_SPEED, True) # Doppler magnitude
# For OPS243-C (combined sensor), you can also enable range magnitude:
# radar.enable_output_mode(OutputMode.MAGNITUDE_RANGE, True) # FMCW magnitude
Units and Sensitivity
# Set measurement units
radar.set_units(Units.KILOMETERS_PER_HOUR) # or METERS_PER_SECOND, MILES_PER_HOUR
# Adjust sensitivity (lower = more sensitive)
radar.set_magnitude_threshold(20) # Default: 20, Range: 1-200+
Filtering
# Filter readings by speed and range
radar.set_speed_filter(min_speed=1.0, max_speed=50.0)
radar.set_range_filter(min_range=0.5, max_range=25.0)
# Range AND Speed Filter (OPS243-C only)
# Only report speeds when objects are within the range filter boundaries
radar.enable_range_and_speed_filter(True)
# Perfect for traffic monitoring with a specific detection zone
Baudrate Configuration
from omnipresense import create_radar, BaudRate
# Automatic detection (recommended - works in most cases)
radar = create_radar('OPS243-C', '/dev/ttyUSB0')
# Specify exact baudrate for faster connection
radar = create_radar('OPS243-C', '/dev/ttyUSB0', baudrate=19200)
# Use BaudRate enum for type safety
radar = create_radar('OPS243-C', '/dev/ttyUSB0', baudrate=BaudRate.BAUD_19200)
# Disable auto-detection (fastest, but requires correct baudrate)
radar = create_radar('OPS243-C', '/dev/ttyUSB0', baudrate=19200, auto_detect_baudrate=False)
Supported Baudrates: 9600, 19200 (default), 57600, 115200, 230400
UART Control Commands:
# Query current sensor baudrate
baud_rate, response = radar.query_baud_rate()
# Change sensor baudrate (requires reconnection)
radar.set_baud_rate(BaudRate.BAUD_57600)
# Save baudrate to persistent memory
radar.save_baudrate_to_memory() # Survives power cycles
Cosine Error Correction
Cosine error occurs when radar is not perpendicular to the target's motion. The radar measures radial velocity: v_radial = v_actual × cos(θ), causing underestimation of actual speed/range.
Hardware-based correction: The sensor applies correction internally using the ^/+ and ^/- commands. Corrected values are transparent to your application.
When to use:
- Side-mounted traffic monitoring
- Angled overhead installations
- Installation constraints requiring non-perpendicular placement
Basic usage:
# Enable correction for 30° angled installation (same angle for both directions)
radar.enable_cosine_correction(30)
# Hardware correction is applied by sensor - readings are pre-corrected
def on_detection(reading):
print(f"Speed: {reading.speed:.1f} km/h") # Already corrected by hardware
radar.start_streaming(on_detection)
Correction factors by angle:
- 15° → 1.035x (3.5% increase)
- 30° → 1.155x (15.5% increase)
- 45° → 1.414x (41.4% increase)
- 60° → 2.000x (100% increase) - unreliable
Important notes:
- Angles > 45° produce unreliable corrections
- Library validates angles (0-89°) and warns for large corrections
- Correction applied by sensor hardware (transparent to application)
- Both speed and range are corrected by hardware
Advanced configuration - Separate inbound/outbound angles:
# For traffic monitoring with lanes at different distances
radar.enable_cosine_correction(
angle_inbound_degrees=25, # Approaching traffic
angle_outbound_degrees=35 # Receding traffic
)
# Disable correction
radar.disable_cosine_correction()
# Query current hardware correction settings
config = radar.get_cosine_correction()
print(f"Enabled: {config.enabled}")
print(f"Inbound angle: {config.angle_inbound_degrees}°")
print(f"Outbound angle: {config.angle_outbound_degrees}°")
See examples/cosine_correction_example.py for detailed demonstrations including traffic monitoring scenarios.
📊 Data Structure
Each radar reading provides:
@dataclass
class RadarReading:
timestamp: float # Unix timestamp
speed: Optional[float] # Speed in configured units
direction: Optional[Direction] # APPROACHING/RECEDING
range_m: Optional[float] # Range in meters
magnitude: Optional[float] # Signal strength
raw_data: Optional[str] # Original data string
🛡️ Error Handling
from omnipresense import RadarError, RadarConnectionError
try:
with create_radar('OPS243-C', '/dev/ttyACM0') as radar:
radar.set_units(Units.METERS_PER_SECOND)
# ... use radar
except RadarConnectionError:
print("Could not connect to radar sensor")
except RadarError as e:
print(f"Radar error: {e}")
Missing Features
The following features from the OmniPreSense API are not yet implemented in this release:
- Hibernation Mode (OPS243 devices) - Low-power hibernation functionality for battery-powered applications
- Rolling Buffer (OPS243-A) - Capturing large sample set from very fast events
🔧 Quick Troubleshooting
No Data Received?
- Enable output modes:
radar.enable_output_mode(OutputMode.SPEED, True) - Create motion: Wave your hand in front of the sensor
- Check distance: Ensure objects are within 0.5m-25m range
- Lower threshold:
radar.set_magnitude_threshold(10)
Permission Denied (Linux)?
sudo usermod -a -G dialout $USER # Add user to dialout group
# Then logout and login again
Port Not Found?
- Linux: Try
/dev/ttyUSB0,/dev/ttyACM0,/dev/ttyACM1 - macOS: Try
/dev/cu.usbmodem*,/dev/cu.usbserial* - Windows: Try
COM3,COM4,COM5, etc.
Connection Failed / Wrong Baudrate?
- Use auto-detection:
create_radar('OPS243-C', '/dev/ttyUSB0')(default) - Try common rates: 19200 (default), 115200 (USB), 9600 (reliable)
- Run diagnostics:
python examples/baudrate_troubleshooting_example.py - Check logs: Enable logging to see detection attempts
import logging
logging.basicConfig(level=logging.INFO) # Shows connection attempts
Need more help? See the comprehensive Troubleshooting Guide.
📚 Documentation & Support
- Troubleshooting Guide - Detailed issue resolution
- Contributing Guide - Development and contribution info
- Examples Directory - Working code examples
- GitHub Issues - Bug reports and feature requests
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for:
- Development environment setup
- Code quality standards
- Testing guidelines
- Pull request process
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
⚖️ Legal Notice
This project is an independent, unofficial implementation developed by the community. It is not affiliated with, endorsed by, or supported by OmniPreSense Corp.
- Trademark: "OmniPreSense" is a trademark of OmniPreSense Corp.
- Hardware: This library is designed to work with OmniPreSense radar sensors
- Support: For hardware issues, contact OmniPreSense directly. For library issues, use our GitHub Issues.
- Warranty: This software comes with no warranty. Use at your own risk.
⭐ Star this repo if it helps you build amazing radar applications! ⭐
Made with ❤️ for the radar sensing community
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file omnipresense-0.2.0.tar.gz.
File metadata
- Download URL: omnipresense-0.2.0.tar.gz
- Upload date:
- Size: 136.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.4.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3790108140b02e5fcff92a1f7b3e3e43b8ce50d5ed395e0dbdad856b731e62e2
|
|
| MD5 |
55131feebdc0961cec092a1611f37586
|
|
| BLAKE2b-256 |
a5cc1c15da7913193e0398ed5b1e91ae7379e8458635b943d8166918f4c4c5bd
|
File details
Details for the file omnipresense-0.2.0-py3-none-any.whl.
File metadata
- Download URL: omnipresense-0.2.0-py3-none-any.whl
- Upload date:
- Size: 25.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.4.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9a535540e067481903fdd5640f1926468afda1d241b4f066492754f0389299a
|
|
| MD5 |
29b1868f58005c64cb82c29e55a3138b
|
|
| BLAKE2b-256 |
344b6fd364f6b092d7769b5f5e42390d08281d818cddd803711db3dda194c650
|