This page describes the current X1-series software interface for build 2493.
The examples below use the default component type olixSense and namespace id001. If the namespace is changed in the WebGUI, replace id001 with the configured namespace.
Source ROS 2 on your computer or on the device:
source /opt/ros2/humble/install/setup.bash
List nodes and topics:
ros2 node list
ros2 topic list
Read the main IMU stream:
ros2 topic echo /olive/olixSense/x1/id001/imu --qos-reliability best_effort
For high publish rates, use Best Effort QoS when possible. Reliable QoS is useful when every sample matters, but it can add latency or backpressure on slow networks.
| Node | Default ROS 2 node name | Purpose |
|---|---|---|
| Manager | /olive_olixSense_id001_manager |
Device configuration, services, restart, WebGUI bridge |
| System | /olive_olixSense_id001_system |
System status and network/device information |
| IMU | /olive_olixSense_id001_imu |
IMU sensing, fusion, calibration, and data publishing |
Default topics use this pattern:
/olive/<component_type>/x1/<namespace>/<publisher_name>
For the default X1-series configuration:
/olive/olixSense/x1/id001/<publisher_name>
| Topic | Message type | Published by | Notes |
|---|---|---|---|
/olive/olixSense/x1/id001/imu |
sensor_msgs/msg/Imu |
IMU | Main fused IMU output. Contains orientation, angular velocity, and linear acceleration. |
/olive/olixSense/x1/id001/acceleration |
geometry_msgs/msg/AccelStamped |
IMU | Gravity-compensated acceleration. |
/olive/olixSense/x1/id001/velocity |
geometry_msgs/msg/TwistStamped |
IMU | Integrated velocity estimate. This can drift over time. |
/olive/olixSense/x1/id001/magneticfield |
sensor_msgs/msg/MagneticField |
IMU | Magnetic field output. Available in IMU mode; disabled in AHRS mode. |
/olive/olixSense/x1/id001/temperature |
sensor_msgs/msg/Temperature |
IMU | Sensor temperature. |
/olive/olixSense/x1/id001/status |
diagnostic_msgs/msg/DiagnosticStatus |
System | Device/system status. |
/tf |
tf2_msgs/msg/TFMessage |
IMU | Only when TF publishing is enabled. |
Debug builds or debug mode may publish extra topics such as feedback, imu_1, imu_2, imu_3, imu_4, or imu_5. These are intended for diagnostics and are not the normal integration interface.
The WebGUI Topics page can override the main user-facing topic names. Topic changes are stored in:
launch_config_manager.yaml
node.topic_publishers
Configurable publishers:
| Node | Publisher keys |
|---|---|
system |
status |
imu |
imu, temperature, velocity, magneticfield, acceleration |
Each publisher entry has:
| Key | Type | Meaning |
|---|---|---|
publisher_name |
string | Internal/display name for the publisher |
use_user_defined |
bool | false uses the Olive default topic rule; true uses user_topic |
user_topic |
string | Full ROS 2 topic path, for example /my_robot/imu/data |
Topic overrides require a device/service restart before all publishers use the new names.
| Service | Type | Description |
|---|---|---|
/olive/olixSense/x1/id001/setBias |
std_srvs/srv/Trigger |
Calibrate bias offsets. Keep the device still while this runs. |
/olive/olixSense/x1/id001/setZeroQuaternion |
std_srvs/srv/Trigger |
Set the current orientation as the local zero reference. |
/olive/olixSense/x1/id001/reboot |
std_srvs/srv/Trigger |
Reboot the device. |
/olive/olixSense/x1/id001/restartDCMServices |
std_srvs/srv/Trigger |
Restart DCM services. |
/olive/olixSense/x1/id001/standby |
std_srvs/srv/SetBool |
Enable or disable standby behavior. |
Examples:
ros2 service call /olive/olixSense/x1/id001/setBias std_srvs/srv/Trigger {}
ros2 service call /olive/olixSense/x1/id001/setZeroQuaternion std_srvs/srv/Trigger {}
The IMU can run in two main modes:
| Mode | Use when | Notes |
|---|---|---|
AHRS |
You need orientation, roll/pitch/yaw behavior, and stable general-purpose output. | Accelerometer sensitivity is fixed internally to 4g. Magnetic field topic is disabled. |
IMU |
You need raw/high-dynamic inertial behavior and configurable accelerometer range. | Supports 2g, 4g, 8g, and 16g acceleration sensitivity. Magnetic field topic is available. |
Change the mode from the WebGUI IMU debug page. A service restart is required.
The coordinate system is configured from the WebGUI IMU debug page and stored in launch_config_imu.yaml under:
node:
coordinate_system: FLU_LEGACY
Available modes:
| Mode | Meaning | Notes |
|---|---|---|
FLU_LEGACY |
Legacy X1 frame behavior | Default for compatibility with existing integrations. |
FLU |
ROS-style Forward, Left, Up linear frame | Z is converted from the legacy sensor convention. |
FRD |
Forward, Right, Down linear frame | Y and Z signs are adjusted from FLU. Common in flight-control integrations. |
For new ROS integrations, use FLU unless your stack expects FRD. Keep FLU_LEGACY if you already have deployed software calibrated against the older behavior.
Acceleration sensitivity is configured from the WebGUI IMU debug page:
node:
sensor_acc_g: 4g
Options are 2g, 4g, 8g, and 16g.
Important behavior:
AHRS mode, the effective range is fixed to 4g for stable orientation behavior.IMU mode, the selected range is applied after restart.Build 2493 can publish the main IMU stream as JSON over UDP or TCP. This is useful for applications that do not use ROS 2, such as PLC gateways, game engines, web services, data loggers, or lightweight scripts.
The X1 device acts as the socket server. Your computer, robot controller, or application connects to the X1 device. The X1 does not open an outgoing connection to your computer.
Open the WebGUI, go to the IMU debug page, then set:
| Setting | Meaning |
|---|---|
| Enable | Turns JSON socket export on or off. |
| Protocol | Selects UDP or TCP. |
| Port | The port where the X1 listens. Default is 5600. |
Apply the setting and restart the device service when the WebGUI asks for it.
The setting is stored in launch_config_imu.yaml:
node:
socket_export:
enabled: true
protocol: UDP
port: 5600
Each payload contains the same main IMU information as the ROS 2 sensor_msgs/msg/Imu output:
| JSON field | Meaning |
|---|---|
schema |
Payload schema version. Current value is olive_imu.v1. |
frame_id |
Frame ID used by the IMU output, for example base_link. |
stamp.sec, stamp.nanosec |
ROS-style timestamp. |
orientation |
Quaternion orientation: x, y, z, w. |
orientation_covariance |
9-value covariance array. |
angular_velocity |
Angular velocity in rad/s. |
angular_velocity_covariance |
9-value covariance array. |
linear_acceleration |
Linear acceleration in m/s^2. |
linear_acceleration_covariance |
9-value covariance array. |
Example payload:
{
"schema": "olive_imu.v1",
"frame_id": "base_link",
"stamp": { "sec": 0, "nanosec": 0 },
"orientation": { "x": 0, "y": 0, "z": 0, "w": 1 },
"orientation_covariance": [0,0,0,0,0,0,0,0,0],
"angular_velocity": { "x": 0, "y": 0, "z": 0 },
"angular_velocity_covariance": [0,0,0,0,0,0,0,0,0],
"linear_acceleration": { "x": 0, "y": 0, "z": 0 },
"linear_acceleration_covariance": [0,0,0,0,0,0,0,0,0]
}
Use TCP when you want a stream connection and simple line-by-line parsing. Each IMU sample is sent as one newline-delimited JSON object.
Quick test:
nc <device-ip> 5600
Python TCP example:
import json
import socket
HOST = "192.168.7.100" # X1 device IP
PORT = 5600
with socket.create_connection((HOST, PORT), timeout=5) as sock:
file = sock.makefile("r")
for line in file:
msg = json.loads(line)
q = msg["orientation"]
acc = msg["linear_acceleration"]
gyro = msg["angular_velocity"]
print(
"q=({x:.4f}, {y:.4f}, {z:.4f}, {w:.4f}) "
"acc=({ax:.3f}, {ay:.3f}, {az:.3f}) "
"gyro=({gx:.3f}, {gy:.3f}, {gz:.3f})".format(
x=q["x"], y=q["y"], z=q["z"], w=q["w"],
ax=acc["x"], ay=acc["y"], az=acc["z"],
gx=gyro["x"], gy=gyro["y"], gz=gyro["z"],
)
)
Use UDP when you want lower overhead and can tolerate packet loss. UDP has no connection handshake, so the client must first send any small packet to the X1. This tells the X1 where to send IMU packets back.
Quick test:
echo hello | nc -u <device-ip> 5600
Python UDP example:
import json
import socket
HOST = "192.168.7.100" # X1 device IP
PORT = 5600
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(5)
# Register this client with the X1. The content is not important.
sock.sendto(b"hello", (HOST, PORT))
while True:
data, _ = sock.recvfrom(65535)
msg = json.loads(data.decode("utf-8"))
q = msg["orientation"]
acc = msg["linear_acceleration"]
gyro = msg["angular_velocity"]
print(
"q=({x:.4f}, {y:.4f}, {z:.4f}, {w:.4f}) "
"acc=({ax:.3f}, {ay:.3f}, {az:.3f}) "
"gyro=({gx:.3f}, {gy:.3f}, {gz:.3f})".format(
x=q["x"], y=q["y"], z=q["z"], w=q["w"],
ax=acc["x"], ay=acc["y"], az=acc["z"],
gx=gyro["x"], gy=gyro["y"], gz=gyro["z"],
)
)
| Protocol | Choose it when | Tradeoff |
|---|---|---|
UDP |
You need low overhead and can accept dropped samples. | Packets can be lost or arrive unevenly. Your client must send one registration packet first. |
TCP |
You want a reliable stream and simple newline-delimited JSON parsing. | If the receiver is slow, TCP can add latency or backpressure. |
For high-rate real-time visualization or control, start with UDP. For logging, debugging, or simple integrations, TCP is often easier.
The WebGUI Parameter page is the recommended way to edit runtime parameters. It shows the active profile values and writes changes to the running ROS 2 parameter service when the target node is available.
CLI examples:
ros2 param list /olive_olixSense_id001_imu
ros2 param set /olive_olixSense_id001_imu publish_rate 200
The Parameter page also protects the user experience after OTA/service restart: if a target node is not available yet, the write is rejected and the WebGUI restores the displayed value.
These parameters exist in both IMU and AHRS profile files.
| Name | Type | Default | Range / Options | What it does |
|---|---|---|---|---|
publish_rate |
int | 100 |
0..1000 Hz |
Main IMU topic publish rate. |
aux_publish_rate |
int | 100 |
1..200 Hz |
Auxiliary topics: temperature, magnetic field, acceleration, velocity, pose, TF, and debug output. |
enable_tf_publisher |
bool | false |
true/false |
Enables /tf output. |
enable_startup_zero_quaternion |
bool | true |
true/false |
Zeros orientation at startup for a local reference. |
acc_cutoff_frequency |
double | 8.0 |
0..500 Hz |
Accelerometer low-pass cutoff. 0 disables the cutoff filter. |
gyro_cutoff_frequency |
double | 8.0 |
0..500 Hz |
Gyroscope low-pass cutoff. 0 disables the cutoff filter. |
topic_publisher_qos |
string | besteffort |
besteffort or reliable |
QoS for IMU publishers. Use besteffort for high-rate streams. |
acc_ema_gain |
double | 0.92 |
0..1 |
Accelerometer EMA gain. Higher follows new data faster; lower smooths more. |
gyro_ema_gain |
double | 0.92 |
0..1 |
Gyroscope EMA gain. Higher follows new data faster; lower smooths more. |
gyro_zero_cutoff_threshold |
double | 0.03 |
0..1 rad/s |
Clips small angular rates to zero. |
acc_scale |
double | 1.0 |
0.5..2.0 |
Global accelerometer output scale. |
gyro_scale |
double | 1.0 |
0.5..2.0 |
Global gyroscope output scale. |
fusion_acc_output_time_constant_sec |
double | 0.0 |
0.0..1.0 |
Smoothing time constant for fused acceleration output. |
fusion_acc_correction_time_constant_sec |
double | 60.0 |
0.1..60.0 |
Long-term acceleration correction speed. |
fusion_acc_temperature_step_gain |
double | 0.0 |
0.0..1.0 |
Extra acceleration correction during temperature changes. |
fusion_acc_base_variance |
double | 0.001 |
1e-8..1.0 |
Baseline acceleration variance for fusion weighting. |
fusion_acc_outlier_gate |
double | 0.08 |
0.0..5.0 |
Acceleration outlier rejection gate. |
fusion_acc_max_correction_alpha |
double | 0.0 |
0.0..1.0 |
Maximum acceleration correction step per cycle. |
fusion_gyro_output_time_constant_sec |
double | 0.0 |
0.0..1.0 |
Smoothing time constant for fused gyro output. |
fusion_gyro_correction_time_constant_sec |
double | 60.0 |
0.1..60.0 |
Long-term gyro correction speed. |
fusion_gyro_temperature_step_gain |
double | 0.0 |
0.0..1.0 |
Extra gyro correction during temperature changes. |
fusion_gyro_base_variance |
double | 0.0001 |
1e-8..1.0 |
Baseline gyro variance for fusion weighting. |
fusion_gyro_outlier_gate |
double | 0.02 |
0.0..5.0 |
Gyro outlier rejection gate. |
fusion_gyro_max_correction_alpha |
double | 0.0 |
0.0..1.0 |
Maximum gyro correction step per cycle. |
| Name | Type | Default | Range | What it does |
|---|---|---|---|---|
mag_cutoff_frequency |
double | 6.0 |
0..500 Hz |
Magnetometer low-pass cutoff. |
mag_ema_gain |
double | 0.92 |
0..1 |
Magnetometer EMA gain. |
fusion_gain |
double | 0.3 |
0..1 |
Fusion beta gain. Higher is more responsive; lower is smoother. |
| Name | Type | Default | Range | What it does |
|---|---|---|---|---|
linear_acc_zero_cutoff_threshold |
double | 0.2 |
0..1 |
Clips small gravity-compensated acceleration values to zero. |
| Name | Type | Default | Range | What it does |
|---|---|---|---|---|
frequency |
int | 1 |
0..10 Hz |
System status publish rate. |
X1-series IMU profiles are selected from the WebGUI IMU debug page:
| Profile | Typical use |
|---|---|
drone |
Faster response for aerial or dynamic motion. This is the default profile. |
mobile_robot |
Ground robot motion with more conservative filtering. |
humanoid |
Body-mounted or walking motion. |
raw |
Less processed output for users who want to filter downstream. |
Changing the profile updates the active IMU parameter file and requires a service restart.
Use setBias or the WebGUI calibration action when the device is completely still. Place the device in its normal mounting orientation before starting calibration.
ros2 service call /olive/olixSense/x1/id001/setBias std_srvs/srv/Trigger {}
Use setZeroQuaternion when the current physical orientation should become the local zero orientation.
ros2 service call /olive/olixSense/x1/id001/setZeroQuaternion std_srvs/srv/Trigger {}
/olive/olixSense/x1/id001/imu for most integrations.acceleration when you need gravity-compensated acceleration as a separate message.velocity as a short-term estimate only; inertial velocity integration drifts over time.