A high-performance Inter-Process Communication (IPC) driver for streaming IMU sensor data between publisher and consumer applications using Unix domain sockets.
This project implements a robust publisher-consumer architecture for IMU (Inertial Measurement Unit) data transmission with:
- Publisher: Generates and streams random IMU sensor data (accelerometer, gyroscope, magnetometer)
- Consumer: Receives IMU data, processes it, and computes orientation (Euler angles + quaternions)
- Real-time capable: Configurable frequency up to 500+ Hz
- Fault-tolerant: Automatic reconnection, timeout handling, malformed data recovery
- Unix domain socket IPC communication
- 12-value IMU payload matching industry-standard struct format
- Real-time orientation computation (roll, pitch, yaw + quaternions)
- Sensor fusion from accelerometer and magnetometer data
- Gimbal lock detection and warnings
- Comprehensive error handling for network failures, timeouts, malformed data
- Automatic reconnection on publisher/consumer disconnect
- Configurable retry logic and timeout management
- Extensive logging with rotating file handlers
- Built-in test mode for robustness validation
- Fully configurable via CLI arguments
- Adjustable transmission frequency (1-1000+ Hz)
- Multiple log levels (DEBUG, INFO, WARNING, ERROR, CRITICAL)
- Optional CSV output for data analysis
- Heartbeat monitoring support
- OS: Debian-based Linux (Ubuntu, Debian)
- Python: 3.6+ (uses standard library only)
- Dependencies: None (pure Python implementation)
git clone https://github.com/Harshvgupta/ipc_socket_communication.git
cd ipc_socket_communication
# Terminal 1: Start Publisher
python3 publisher.py --socket-path /tmp/imu_socket --frequency-hz 500 --log-level INFO
# Terminal 2: Start Consumer
python3 consumer.py --socket-path /tmp/imu_socket --timeout-ms 100 --log-level INFO
python3 publisher.py --socket-path /tmp/imu_socket --frequency-hz 100
python3 publisher.py \
--socket-path /tmp/imu_socket \
--frequency-hz 500 \
--log-level DEBUG \
--log-dir ./logs \
--heartbeat-every 1000 \
--test-mode true
python3 consumer.py --socket-path /tmp/imu_socket --timeout-ms 100
python3 consumer.py \
--socket-path /tmp/imu_socket \
--timeout-ms 100 \
--log-level DEBUG \
--log-dir ./logs \
--output-csv ./imu_data.csv
Parameter | Required | Default | Description |
---|---|---|---|
--socket-path | Yes | - | Unix domain socket file path |
--frequency-hz | No | 100 | IMU data transmission rate (Hz) |
--log-level | No | INFO | Logging verbosity level |
--log-dir | No | "" | Directory for rotating log files |
--heartbeat-every | No | 0 | Send heartbeat every N packets (0=disabled) |
--test-mode | No | false | Inject malformed data for testing |
Parameter | Required | Default | Description |
---|---|---|---|
--socket-path | Yes | - | Unix domain socket file path |
--timeout-ms | No | 100 | Socket read timeout (milliseconds) |
--log-level | No | INFO | Logging verbosity level |
--log-dir | No | "" | Directory for rotating log files |
--output-csv | No | "" | CSV file path for orientation output |
DEBUG
: Detailed packet-level informationINFO
: General operational messagesWARNING
: Non-critical issues (timeouts, malformed data)ERROR
: Recoverable errorsCRITICAL
: Fatal errors requiring restart
The publisher generates 12-value CSV packets matching this C struct:
typedef struct {
float xAcc; // Acceleration X [mg]
float yAcc; // Acceleration Y [mg]
float zAcc; // Acceleration Z [mg]
uint32_t timestampAcc; // Accelerometer timestamp [ms]
int32_t xGyro; // Gyro X [mDeg/s]
int32_t yGyro; // Gyro Y [mDeg/s]
int32_t zGyro; // Gyro Z [mDeg/s]
uint32_t timestampGyro; // Gyroscope timestamp [ms]
float xMag; // Magnetometer X [mGauss]
float yMag; // Magnetometer Y [mGauss]
float zMag; // Magnetometer Z [mGauss]
uint32_t timestampMag; // Magnetometer timestamp [ms]
} __attribute__((packed)) Payload_IMU_t;
0.4343,0.9443,0.2225,1721931959,546,797,221,1721931959,0.9756,0.1212,0.8567,1721931959
- Accelerometer: ±2000 mg (±2g)
- Gyroscope: ±250,000 mDeg/s (±250°/s)
- Magnetometer: ±4800 mGauss (±4.8 Gauss)
- Timestamps: Milliseconds since Unix epoch
[2024-06-06 10:30:15] [INFO] IMUConsumer: Orientation | AccTs=1721931959 | Roll=15.23°, Pitch=-8.45°, Yaw=185.67° | Quat=(w=0.9876, x=0.1234, y=-0.0567, z=0.0890)
timestamp_ms,roll_deg,pitch_deg,yaw_deg
1721931959,15.2300,-8.4500,185.6700
1721931960,15.1800,-8.5200,185.7100
Publisher → Unix Socket → Consumer
↓ ↓ ↓
Generate Transport Process
IMU Data via IPC & Filter
↓ ↓ ↓
Random Low-latency Compute
Sensors Reliable Orientation
- Unix Domain Sockets: Chosen over TCP for lower latency local IPC
- Text-based Protocol: CSV format for easier debugging and cross-platform compatibility
- Automatic Reconnection: Consumer reconnects on publisher restart
- Sensor Fusion: Accelerometer for roll/pitch, magnetometer for yaw
- Gimbal Lock Handling: Detection and warnings when pitch approaches ±90°
- Network Errors: Automatic reconnection with exponential backoff
- Malformed Data: Skip invalid packets, log warnings, continue processing
- Timeouts: Configurable timeout with graceful degradation
- Resource Cleanup: Proper socket cleanup on shutdown signals
# Run comprehensive unit tests
python3 -m unittest test_imu_ipc.py -v
# Test with realistic load
python3 publisher.py --socket-path /tmp/test --frequency-hz 500 --test-mode true &
python3 consumer.py --socket-path /tmp/test --timeout-ms 50 --log-level DEBUG
# High-frequency stress test
python3 publisher.py --socket-path /tmp/bench --frequency-hz 1000 &
python3 consumer.py --socket-path /tmp/bench --timeout-ms 10
# High-frequency IMU for drone navigation
python3 publisher.py --socket-path /tmp/drone_imu --frequency-hz 500 &
python3 consumer.py --socket-path /tmp/drone_imu --output-csv /var/log/drone_orientation.csv
# Debug mode with detailed logging
python3 publisher.py --socket-path /tmp/debug --frequency-hz 10 --log-level DEBUG --test-mode true &
python3 consumer.py --socket-path /tmp/debug --log-level DEBUG --timeout-ms 1000
# Long-term data collection
python3 publisher.py --socket-path /tmp/datacollect --frequency-hz 100 &
python3 consumer.py --socket-path /tmp/datacollect --output-csv ./long_term_data.csv --log-dir ./logs
# Ensure publisher is started first
python3 publisher.py --socket-path /tmp/imu_socket --frequency-hz 100 &
# Wait 1-2 seconds, then start consumer
python3 consumer.py --socket-path /tmp/imu_socket --timeout-ms 100
# Use writable socket path
python3 publisher.py --socket-path ~/imu_socket --frequency-hz 100
# Reduce frequency for testing
python3 publisher.py --socket-path /tmp/imu_socket --frequency-hz 50
# Ensure log directory exists and is writable
mkdir -p ./logs
chmod 755 ./logs
python3 consumer.py --socket-path /tmp/imu_socket --log-dir ./logs
# Check socket existence
ls -la /tmp/imu_socket
# Monitor socket connections
sudo netstat -xa | grep imu_socket
# Check process status
ps aux | grep publisher
ps aux | grep consumer
- Latency: < 1ms end-to-end at 100Hz
- Throughput: 1000+ packets/second sustained
- Memory: < 10MB RSS per process
- CPU: < 5% on modern systems at 500Hz
- High Frequency: Use dedicated CPU cores for RT performance
- Low Latency: Minimize timeout values (--timeout-ms 10)
- Logging: Use INFO level for production, DEBUG only for development
- File I/O: Place CSV output on SSD for high-frequency logging
# Send heartbeat every 1000 packets
python3 publisher.py --heartbeat-every 1000 --socket-path /tmp/imu_socket
# Inject malformed data every 500 packets
python3 publisher.py --test-mode true --socket-path /tmp/imu_socket
# 10MB log files, keep 5 backups
python3 consumer.py --log-dir ./logs --socket-path /tmp/imu_socket
roll = atan2(yAcc, zAcc)
pitch = atan2(-xAcc, sqrt(yAcc² + zAcc²))
magXc = xMag * cos(pitch) + zMag * sin(pitch)
magYc = xMag * sin(roll) * sin(pitch) + yMag * cos(roll) - zMag * sin(roll) * cos(pitch)
yaw = atan2(-magYc, magXc)
qw = cos(roll/2) * cos(pitch/2) * cos(yaw/2) + sin(roll/2) * sin(pitch/2) * sin(yaw/2)
qx = sin(roll/2) * cos(pitch/2) * cos(yaw/2) - cos(roll/2) * sin(pitch/2) * sin(yaw/2)
qy = cos(roll/2) * sin(pitch/2) * cos(yaw/2) + sin(roll/2) * cos(pitch/2) * sin(yaw/2)
qz = cos(roll/2) * cos(pitch/2) * sin(yaw/2) - sin(roll/2) * sin(pitch/2) * cos(yaw/2)
- Coordinate System: Standard NED (North-East-Down) orientation
- Sensor Alignment: All sensors perfectly aligned (no calibration matrix)
- Static Calibration: No runtime bias compensation
- Magnetic Declination: Not compensated (raw magnetic north)
- Local Gravity: Assumes standard gravity (9.81 m/s²)
- No Real-time Scheduling: Standard process priority (not RT tasks)
- Simple Sensor Fusion: No Kalman filtering or advanced fusion
- No Sensor Calibration: Raw sensor values used directly
- Single Consumer: Publisher supports one consumer at a time
- Text Protocol: CSV overhead vs. binary protocols
- Real-time task scheduling (SCHED_FIFO)
- Kalman filter implementation
- Multi-consumer support
- Binary protocol option
- Sensor calibration routines
- Web-based monitoring dashboard
This project is provided as-is for educational and development purposes.
- 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
For issues, questions, or contributions, please:
- Check existing issues in the repository
- Create a new issue with detailed description
- Include log outputs and system information
- Provide minimal reproduction steps
Author: Harsh Gupta
Repository: https://github.com/Harshvgupta/ipc_socket_communication
Last Updated: June 2024