Target Node AI

Target Node AI Anomaly Detection (Target Node AD)

Detecting Anomalies That Manual Thresholds Miss

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.

Examples

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.

Drone: A Failing Motor

The Example: A Failing Motor

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 Drone

  • Platform: PX4 x500 quadrotor, simulated in Gazebo (software-in-the-loop)
  • Flight: Autonomous waypoint route, about 3 minutes long
  • Recorded: Onboard IMU (3-axis accelerometer + 3-axis gyro) and velocity estimates

The Injected Fault

  • Fault: Front-left rotor weakened to 95% of commanded thrust (5% loss)
  • Onset: Ramped in gradually over 20 seconds
  • Timing: Injected during a climb and held for ~60 seconds
  • Result: Autopilot compensated using the other motors, so the drone flew its route normally

What Target Node AD Watches

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

What Was Detected

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
  • No single-channel threshold would have triggered.
  • This is a multivariate anomaly: The combinations of all 9 signals deviated from normal patterns.
  • Target Node AD learned the healthy group behavior, so the weak motor stood out clearly.
Ground Robot: A Slipping Wheel

The Example: A Slipping Wheel

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 Robot

  • Platform: TurtleBot 3 Burger, simulated in Gazebo
  • Route: Autonomous waypoint patrol driven by the ROS navigation stack (move_base), about 5.5 minutes long
  • Recorded: Wheel speeds (both wheels), wheel odometry, and onboard IMU (3-axis accelerometer + 3-axis gyro)

The Injected Fault

  • Fault: Left wheel ground traction cut in half — surface friction lowered from 0.1 to 0.05
  • Duration: Present for the entire run — the wheel drove with reduced grip from the first waypoint to the last
  • Result: The navigation stack compensated with continuous steering corrections, so the robot drove its route normally and reached every waypoint with no skips

What Target Node AD Watches

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

What Was Detected

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
  • No single-channel threshold would have triggered.
  • This is a multivariate anomaly: The combinations of all 10 signals deviated from normal patterns.
  • Target Node AD learned the healthy group behavior, so the slipping wheel stood out clearly.
Robot Arm: An Overweight Payload

The Example: An Overweight Payload

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 Arm

  • Platform: Universal Robots UR5e (6-joint arm), simulated in Gazebo
  • Task: Autonomous pick-and-place — lift an object from the left, carry it over an arc, and set it down on the right — carrying objects from 0 to 1 kg, about 6 minutes long
  • Recorded: Per-joint effort, position, and velocity for all six joints (shoulder_pan, shoulder_lift, elbow, wrist_1, wrist_2, wrist_3)

The Injected Fault

  • Fault: An unexpected additional payload of about 0.6 kg on the end-effector, beyond the 0–1 kg the arm was trained on
  • Onset: Ramped in over 2 seconds
  • Timing: Held for 30 seconds while the arm carried objects through its pick-and-place cycles
  • Result: The joint effort controllers compensated for the extra weight, so the arm completed every pick-and-place normally

What Target Node AD Watches

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]

What Was Detected

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
  • No single-channel threshold would have triggered.
  • The load has no fixed signature: an unexpected weight produces different joint torques depending on the arm’s pose, so no single channel reliably reflects it, meaning there is no one place to set a threshold.
  • This is a multivariate anomaly: The combinations of all 18 signals deviated from normal patterns.
  • Target Node AD learned the healthy group behavior, so the overweight payload stood out clearly.

Bottom Line

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.