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 • 📚 Documentation • 💡 Examples • 🤝 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
- 📚 Well Documented - Extensive docstrings and usage examples
📡 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, SamplingRate
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.METERS_PER_SECOND)
radar.set_sampling_rate(SamplingRate.HZ_10000)
radar.set_magnitude_threshold(20)
# Define callback for radar data
def on_detection(reading):
if reading.speed and reading.speed > 1.0:
print(f"Speed: {reading.speed:.2f} m/s")
print(f"Direction: {reading.direction.value}")
print(f"Magnitude: {reading.magnitude}")
# Start streaming data
radar.start_streaming(on_detection)
time.sleep(10) # Stream for 10 seconds
📋 Requirements
- Python: 3.8.1+
- Dependencies:
pyserial>= 3.4
💡 Examples
Basic Usage
from omnipresense import create_radar, Units
radar = create_radar('OPS243-C', '/dev/ttyACM0')
with radar:
radar.set_units(Units.METERS_PER_SECOND)
def on_detection(reading):
if reading.speed:
print(f"Speed: {reading.speed:.2f} m/s")
if reading.range_m:
print(f"Range: {reading.range_m:.2f} m")
radar.start_streaming(on_detection)
📁 More Examples: See the
examples/directory for additional scripts including Doppler-only sensors, FMCW sensors, debugging tools, and advanced configurations.
⚙️ Advanced Configuration
Power Management
from omnipresense import PowerMode
# Set power modes for battery optimization
radar.set_power_mode(PowerMode.IDLE) # Low power mode
radar.set_duty_cycle(100, 1000) # 100ms active, 1000ms sleep
Data Output Formats
from omnipresense import OutputMode
# Enable multiple output modes
radar.enable_json_output(True) # JSON format
radar.enable_magnitude_output(True) # Signal strength
radar.enable_timestamp_output(True) # Timestamps
radar.set_data_precision(3) # 3 decimal places
Filtering and Thresholds
# Advanced filtering
radar.set_speed_filter(min_speed=0.5, max_speed=50.0)
radar.set_range_filter(min_range=2.0, max_range=25.0)
radar.set_magnitude_threshold(50) # Noise filtering
📊 Data Structure
The RadarReading object contains:
@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
ℹ️ Sensor Information
# Get comprehensive sensor info
info = radar.get_sensor_info()
print(f"Model: {info.model}")
print(f"Firmware: {info.firmware_version}")
print(f"Detection Range: {info.detection_range}")
print(f"Features: Doppler={info.has_doppler}, FMCW={info.has_fmcw}")
# Query specific details
print(f"Frequency: {radar.get_frequency()} Hz")
print(f"Board ID: {radar.get_board_id()}")
🛡️ Error Handling
from omnipresense import (
RadarError, RadarConnectionError,
RadarCommandError, RadarValidationError
)
try:
with create_radar('OPS241-A', '/dev/ttyUSB0') as radar:
radar.set_units(Units.METERS_PER_SECOND)
# ... use radar
except RadarConnectionError:
print("Could not connect to radar sensor")
except RadarValidationError as e:
print(f"Configuration error: {e}")
except RadarError as e:
print(f"Radar error: {e}")
📚 Documentation
- API Reference - Complete method documentation
- Hardware Guide - Sensor setup and wiring
- Examples - Complete working examples
- Troubleshooting - Common issues and solutions
🔧 Development
Setup Development Environment
git clone https://github.com/yourusername/OmnipresenseRadar.git
cd OmnipresenseRadar
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install development dependencies
pip install -e ".[dev]"
# Install pre-commit hooks
pre-commit install
Running Tests
# Run all tests
pytest
# Run with coverage
pytest --cov=omnipresense
# Run specific test file
pytest tests/test_doppler_radar.py -v
Code Quality
# Run all pre-commit hooks on all files
pre-commit run --all-files
# Format code manually (if needed)
black omnipresense/ tests/
# Type checking
mypy omnipresense/
# Linting with ruff
ruff check omnipresense/ tests/
ruff format omnipresense/ tests/
# Security scanning
bandit -r omnipresense/
Pre-commit Hooks
This project uses pre-commit hooks to ensure code quality. The following checks run automatically on each commit:
- Code Formatting: Black, isort for consistent style
- Linting: Ruff for code quality and style issues
- Type Checking: MyPy for static type analysis
- Security: Bandit for security vulnerability scanning
- Dependencies: Safety for known security vulnerabilities
- Documentation: Pydocstyle for docstring conventions
- Import Management: Autoflake removes unused imports
- Syntax Upgrades: PyUpgrade modernizes Python syntax
- Commit Messages: Conventional commit format validation
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Ways to Contribute
- 🐛 Bug Reports - Found an issue? Let us know!
- 💡 Feature Requests - Have ideas? We'd love to hear them!
- 📚 Documentation - Help improve our docs
- 🧪 Testing - Add tests for better coverage
- 💻 Code - Fix bugs or add new features
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- OmniPreSense for creating excellent radar sensors and comprehensive documentation
- Contributors who help improve this library
- Community for feedback and bug reports
⚖️ 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.
🔧 Troubleshooting
Common Issues
Permission Denied (Linux/macOS)
PermissionError: [Errno 13] Permission denied: '/dev/ttyUSB0'
Solution for Linux:
# Add your user to the dialout group
sudo usermod -a -G dialout $USER
# Log out and log back in for changes to take effect
# Or reboot your system
Solution for macOS:
# Give permission to the serial port
sudo chmod 666 /dev/cu.usbmodem*
# Or run your Python script with sudo (not recommended)
Port Not Found
FileNotFoundError: could not open port /dev/ttyUSB0: No such file or directory
Solutions:
- Check if device is connected:
ls /dev/tty*(Linux/macOS) or check Device Manager (Windows) - Try different port names:
- Linux:
/dev/ttyUSB0,/dev/ttyUSB1,/dev/ttyACM0,/dev/ttyACM1 - macOS:
/dev/cu.usbmodem*,/dev/cu.usbserial* - Windows:
COM3,COM4,COM5, etc.
- Linux:
- Install drivers: Some radar modules may need specific USB-to-serial drivers
No Data Received
# Radar connects but no readings in callback
Solutions:
- Check detection range: Ensure objects are within sensor's detection range
- Adjust thresholds: Lower magnitude threshold for more sensitivity
- Check power mode: Ensure sensor is in active mode
- Verify configuration: Check units, sampling rate, and filters
Import Errors
ModuleNotFoundError: No module named 'omnipresense'
Solutions:
- Install package:
pip install omnipresense - Development install:
pip install -e .(from project root) - Check Python environment: Ensure you're using the correct virtual environment
Windows COM Port Issues
On Windows, you may need to:
- Check Device Manager for the correct COM port number
- Install proper USB drivers for your radar module
- Try different COM ports (COM3, COM4, COM5, etc.)
Getting Help
If you're still experiencing issues:
-
Check sensor specifications: Verify your radar model and its capabilities
-
Review examples: Look at the examples in the
examples/directory -
Enable debug logging: Add logging to see detailed communication
import logging logging.basicConfig(level=logging.DEBUG)
-
Hardware verification: Test with OmniPreSense's official software first
🆘 Support
- GitHub Issues: Report bugs or request features
- Documentation: Read the full docs
- Email: graeb.oskar@gmail.com
⭐ 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.1.0.tar.gz.
File metadata
- Download URL: omnipresense-0.1.0.tar.gz
- Upload date:
- Size: 105.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.4.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c87ec5dd3b1374e5d4543d237194dfbd7b06ec120bf7b65d2d2cbcac20525fce
|
|
| MD5 |
d304bad39c145f97a42a9a09e52edd79
|
|
| BLAKE2b-256 |
6637a44c526fabb9c271068323bffbf73545323135445fe660c07931122968f5
|
File details
Details for the file omnipresense-0.1.0-py3-none-any.whl.
File metadata
- Download URL: omnipresense-0.1.0-py3-none-any.whl
- Upload date:
- Size: 17.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.4.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b825e818650402e3c3fabd17e1c1c9632f1aafb7909774d691a641fac5e65a43
|
|
| MD5 |
0950b8164a3d5d5621a30b9e8353248e
|
|
| BLAKE2b-256 |
7129d271cb6ae09b159c332e198afa7539e990eac866724a087624bc5acf1d95
|