Author: shane@targetnode.ai
Demo video: Target Node Anomaly Detection
This document shows how Target Node AD catches problems that manual thresholds miss. Specifically, multivariate anomalies.
A common way to monitor robot health is to set min/max limits on each sensor and raise an alarm when a reading goes out of range. This works for big, obvious failures. However, it misses a whole class of faults where every sensor can read as normal individually but the relationships between the readings are anomalous. These faults are very difficult (or impossible) to catch with manual thresholds.
Target Node AD learns what the sensors normally look like together, so it detects faults even when all individual readings appear normal.
Each example below injects a compensated fault into a different simulated robot. The fault never shows up as an abnormal reading on any individual sensor, yet Target Node AD detects it anyway.
A motor gradually losing thrust is a fault an autopilot can hide: it compensates, so the drone continues flying normally while the problem worsens.
We simulated and detected this fault.
The model treats these nine signals from two topics as one group. It analyzes them together and learns their normal relationships:
| Signals | Topic | Fields |
|---|---|---|
| IMU (3-axis accel + gyro) | /fmu/out/sensor_combined | accelerometer_m_s2[0/1/2], gyro_rad[0/1/2] |
| Velocity (3 axes) | /fmu/out/vehicle_local_position_v1 | vx, vy, vz |
Target Node AD successfully flagged the weakened motor despite the autopilot’s corrections. No sensor reading ever left the normal training range:
| Sensor | Field | Error Score | Value During Fault | Normal Training Range |
|---|---|---|---|---|
| Vertical accel | accelerometer_m_s2[2] | 0.231 | −11.9 to −8.0 | −13.3 to −4.1 |
| Sideways speed | vy | 0.042 | −2.1 to 1.9 | −4.8 to 4.5 |
| Vertical speed | vz | 0.041 | −0.2 to 0.3 | −2.3 to 2.1 |
| Sideways accel | accelerometer_m_s2[1] | 0.035 | −0.1 to 0.1 | −0.5 to 0.5 |
| Forward accel | accelerometer_m_s2[0] | 0.022 | −0.6 to 0.0 | −0.6 to 0.4 |
| Pitch rate | gyro_rad[1] | 0.020 | −1.7 to 0.6 | −1.8 to 1.0 |
| Yaw rate | gyro_rad[2] | 0.008 | −0.4 to 1.0 | −2.9 to 2.9 |
| Roll rate | gyro_rad[0] | 0.004 | −0.1 to 0.3 | −1.7 to 2.2 |
| Forward speed | vx | 0.0003 | −2.0 to 1.5 | −4.8 to 4.5 |
A wheel gradually losing grip is a fault a navigation stack can hide: it compensates, so the robot continues driving its route normally while the problem persists.
We simulated and detected this fault.
The model treats these ten signals from three topics as one group. It analyzes them together and learns their normal relationships:
| Signals | Topic | Fields |
|---|---|---|
| Wheel speeds | /joint_states | velocity[0], velocity[1] |
| Odometry | /odom | twist.twist.linear.x, twist.twist.angular.z |
| IMU (3-axis accel + gyro) | /imu | angular_velocity.x/y/z, linear_acceleration.x/y/z |
Target Node AD successfully flagged the slipping wheel despite the navigation stack’s corrections. No sensor reading ever left the normal training range:
| Sensor | Field | Error Score | Value During Fault | Normal Training Range |
|---|---|---|---|---|
| Left wheel speed | velocity[0] | 0.381 | −4.7 to 8.0 | −7.8 to 8.9 |
| Right wheel speed | velocity[1] | 0.279 | −5.0 to 8.2 | −7.0 to 8.4 |
| Forward speed | twist.twist.linear.x | 0.250 | −0.1 to 0.2 | −0.2 to 0.2 |
| Pitch rate | angular_velocity.y | 0.083 | −0.01 to 0.01 | −0.01 to 0.01 |
| Lateral accel | linear_acceleration.y | 0.038 | −0.5 to 0.5 | −0.6 to 0.7 |
| Roll rate | angular_velocity.x | 0.018 | −0.01 to 0.01 | −0.01 to 0.01 |
| Vertical accel | linear_acceleration.z | 0.014 | −0.1 to 0.1 | −0.1 to 0.1 |
| Yaw rate (odom) | twist.twist.angular.z | 0.005 | −1.6 to 1.8 | −1.6 to 1.9 |
| Yaw rate (IMU) | angular_velocity.z | 0.000 | −1.6 to 1.8 | −1.6 to 1.9 |
| Forward accel | linear_acceleration.x | 0.000 | −0.6 to 0.6 | −0.7 to 0.8 |
A payload heavier than the arm was trained on is a fault the joint controllers can hide: they compensate, so the arm keeps performing its task normally while the extra load persists.
We simulated and detected this fault.
The model treats these eighteen signals from one topic as one group. It analyzes them together and learns their normal relationships:
| Signals | Topic | Fields |
|---|---|---|
| Joint effort (6 joints) | /joint_states | effort[0], effort[1], effort[2], effort[3], effort[4], effort[5] |
| Joint position (6 joints) | /joint_states | position[0], position[1], position[2], position[3], position[4], position[5] |
| Joint velocity (6 joints) | /joint_states | velocity[0], velocity[1], velocity[2], velocity[3], velocity[4], velocity[5] |
Target Node AD successfully flagged the overweight payload despite the controllers’ compensation. No sensor reading ever left the normal training range:
| Sensor | Field | Error Score | Value During Fault | Normal Training Range |
|---|---|---|---|---|
| Wrist-2 velocity | velocity[4] | 0.004532 | −0.75 to 0.78 | −0.90 to 0.87 |
| Shoulder-pan position | position[2] | 0.004519 | −1.44 to 1.45 | −1.45 to 1.45 |
| Elbow position | position[0] | 0.003398 | 1.22 to 1.79 | 1.21 to 1.81 |
| Wrist-1 effort | effort[3] | 0.003268 | −3.2 to −1.0 | −3.3 to −0.6 |
| Shoulder-pan velocity | velocity[2] | 0.001767 | −0.39 to 0.38 | −0.41 to 0.40 |
| Shoulder-lift velocity | velocity[1] | 0.000898 | −0.21 to 0.20 | −0.23 to 0.20 |
| Wrist-3 velocity | velocity[5] | 0.000774 | −0.16 to 0.15 | −0.16 to 0.16 |
| Wrist-1 position | position[3] | 0.000766 | −2.19 to −1.65 | −2.20 to −1.65 |
| Wrist-2 effort | effort[4] | 0.000749 | −1.5 to 1.6 | −1.7 to 1.8 |
| Elbow effort | effort[0] | 0.000734 | −26.8 to −12.8 | −27.9 to −9.3 |
| Elbow velocity | velocity[0] | 0.000711 | −0.14 to 0.24 | −0.19 to 0.29 |
| Shoulder-lift position | position[1] | 0.000642 | −1.50 to −0.70 | −1.50 to −0.69 |
| Shoulder-lift effort | effort[1] | 0.000600 | −93.1 to 15.7 | −96.8 to 19.0 |
| Wrist-3 position | position[5] | 0.000122 | −0.15 to 0.13 | −0.15 to 0.15 |
| Wrist-2 position | position[4] | 0.000035 | −1.72 to −1.42 | −1.72 to −1.42 |
| Wrist-3 effort | effort[5] | 0.000028 | −0.02 to 0.02 | −0.02 to 0.02 |
| Shoulder-pan effort | effort[2] | 0.000009 | −79.3 to 73.3 | −83.5 to 75.4 |
| Wrist-1 velocity | velocity[3] | 0.000003 | −0.29 to 0.26 | −0.32 to 0.27 |
Compensated faults like a drone’s degrading motor, a ground robot’s slipping wheel, and a robot arm’s overweight payload can be very difficult to catch with manual thresholds without generating excessive false alarms. In each of these examples, no single sensor reading ever left its normal range and Target Node AD flagged the problem anyway. Target Node AD performs both multivariate and univariate anomaly detection to surface these issues early, helping keep your robots safer and more reliable.