---
abstract: |
  We introduce the first universal pretraining corpus for industrial time-series data: **FactoryNet**. 51M datapoints across 23k end-to-end task executions (13.3k real, 9.8k synthetic) on six embodiments, unified by a shared schema that enables robust zero-shot cross-embodiment transfer and highly parameter-efficient anomaly detection. We introduce a novel schema: Setpoint, Effort, Feedback, Context (S-E-F-C) underlying the whole pipeline that maps any actuated system into a common representational frame. The corpus spans 27 annotated anomaly types alongside healthy baselines and counterfactual pairs across robotic manipulation and machining domains. Cross-embodiment transfer experiments yield positive results: under bias-aware metrics our model demonstrates fair cross-embodiment transfer capabilities on the evaluated source-target pair, while 24 schema-aligned signals achieves competitive anomaly detection performance compared to high-dimensional baselines. We release FactoryNet as a growing, multi-embodiment dataset to drive progress toward industrial foundation models.
author:
- Karim Othman
- Jonas Petersen
- Matei Ignuta-Ciuncanu
- Camilla Mazzoleni
- Federico Martelli
- Gian-Alessandro Lombardi
- Riccardo Maggioni
- Philipp Petersen
title: "FactoryNet: A Large-Scale Dataset toward Industrial Time-Series Foundation Models"
bibliography:
- factorynet.bib
---

# Abstract

We introduce the first universal pretraining corpus for industrial time-series data: **FactoryNet**. 51M datapoints across 23k end-to-end task executions (13.3k real, 9.8k synthetic) on six embodiments, unified by a shared schema that enables robust zero-shot cross-embodiment transfer and highly parameter-efficient anomaly detection. We introduce a novel schema: Setpoint, Effort, Feedback, Context (S-E-F-C) underlying the whole pipeline that maps any actuated system into a common representational frame. The corpus spans 27 annotated anomaly types alongside healthy baselines and counterfactual pairs across robotic manipulation and machining domains. Cross-embodiment transfer experiments yield positive results: under bias-aware metrics our model demonstrates fair cross-embodiment transfer capabilities on the evaluated source-target pair, while 24 schema-aligned signals achieves competitive anomaly detection performance compared to high-dimensional baselines. We release FactoryNet as a growing, multi-embodiment dataset to drive progress toward industrial foundation models.

# Introduction

The manufacturing sector accounts for approximately 15% of global GDP, relying heavily on the continuous operation of complex actuated machinery [@WB_NV.IND.MANF.ZS]. While predictive maintenance and process optimization present significant opportunities for machine learning, industrial AI remains largely confined to single-machine, bespoke deployments. Foundation models have transformed vision and language by pretraining on large, structurally coherent corpora  [@brown2020language; @dosovitskiy2020image], yet no analogous substrate exists for industrial time-series. The gap is not merely volume: existing anomaly detection and forecasting datasets [@Brockmann2023TheVD; @leporowski2021aursad] record sensor outcomes without separating *commanded intent* from *measured response*. For actuated systems, learning transferable dynamics requires observing the full control loop from target trajectory through actuation effort to the resulting physical state. While partial solutions exist for specific machines (as discussed in Section `\ref{sec:related}`{=latex}), no unified open dataset provides this explicit decomposition across multiple embodiments.

Every signal is mapped into the Setpoint-Effort-Feedback-Context (S-E-F-C) schema: a machine-agnostic signal taxonomy grounded in IEC 81346 functional classification that separates intent from outcome across arbitrary actuated systems. For physics-oriented modeling, S--E--F--C plays the role of a compact, structured interface for short rollouts: Setpoint and Context fix commanded intent and boundary conditions, while Effort and Feedback make *commanded versus realized* dynamics comparable as explicit prediction residuals rather than opaque reconstruction scores. Paired real and Isaac episodes under the same schema let sim-to-real mismatch be read as *forward-model error* under matched inputs, in line with the bias-aware transfer and phase-aware gap analyses.

# Related Work {#sec:related}

## Industrial Fault-Detection Datasets

The availability of open-source data in the manufacturing domain lags significantly behind other modalities. Most existing datasets focus on single-machine, run-to-failure scenarios or specific rotating machinery components. Canonical examples include the NASA C-MAPSS turbofan degradation benchmark [@saxena2008damage] and recent robotic datasets: voraus-AD [@Brockmann2023TheVD] provides 2,122 episodes of industrial robot recordings and AURSAD [@leporowski2021aursad] offers 2,045 episodes. However, these datasets are bounded in scale and lack an explicit control-loop structure mapping commands to outcomes. By unifying these sources alongside novel laboratory data under a standard control-theoretic decomposition, FactoryNet provides the largest open-source, fault-injected industrial robot dataset to date (see Table `\ref{tab:dataset_comparison}`{=latex} for a comprehensive comparison with existing datasets).

Beyond single-component datasets, broader industrial anomaly detection benchmarks such as SKAB [@skab], MetroPT [@veloso2022benchmarkdatasetpredictivemaintenance], WADI [@WADI2017testbed] and the Tennessee-Eastman process [@downs1993plant] provide system-level multivariate time-series. Similarly, general-purpose time-series anomaly detection benchmarks like TSB-AD [@liu2024elephant] and TODS [@lai2025todsautomatedtimeseries] have driven algorithmic progress (e.g., Anomaly-Transformer [@xu2022anomaly]). However, these datasets record holistic system states without the explicit commanded-versus-measured structural decomposition necessary for learning robotic dynamics.

```{=latex}
\begin{table*}[t]

    \caption{Comparison of open-source industrial time-series datasets. Expanding beyond single-domain recordings, FactoryNet is the only multi-machine corpus requiring a strict control-loop structure decoupling intended Setpoint from applied Effort.}
    \label{tab:dataset_comparison}
    \resizebox{\textwidth}{!}{%
        \begin{tabular}{lcllccc}
            \toprule
            \textbf{Dataset}                    & \textbf{Year} & \textbf{Machine Type}  & \textbf{Signals}    & \textbf{Samples (Eps.)} & \textbf{Has Setpoint?}  & \textbf{Has Effort?}    \\
            \midrule
            CWRU~\cite{cwru}                    & 2000          & Bearings               & Vibration           & 480                     & No                      & No                      \\
            PHM 2010~\cite{phm2010}             & 2010          & CNC milling            & Force, vibration    & 315                     & Partial                 & Yes                     \\
            Paderborn~\cite{paderborn}          & 2016          & Bearings               & Vibration, current  & 2,000                   & No (RPM only)           & Partial                 \\
            MAFAULDA~\cite{mafaulda}            & 2016          & Rotating machinery     & Vibration, audio    & 1,951                   & No                      & No                      \\
            XJTU-SY~\cite{xjtu}                 & 2019          & Bearings               & Vibration           & 15                      & No                      & No                      \\
            AURSAD~\cite{leporowski2021aursad}  & 2021          & UR3e robot             & Joint signals       & 2,045                   & Yes                     & Yes                     \\
            voraus-AD~\cite{Brockmann2023TheVD} & 2023          & Collaborative robot    & 130 channels        & 2,122                   & Yes                     & Yes                     \\
            \midrule
            \textbf{FactoryNet (Ours)}          & \textbf{2026} & \textbf{Multi-machine} & \textbf{Multimodal} & \textbf{23k}            & \textbf{Yes (Required)} & \textbf{Yes (Required)} \\
            \bottomrule
        \end{tabular}%
    }
\end{table*}
```
## Foundation Models for Time-Series and Robotics

Current foundation model research diverges into two distinct tracks. In robotics, efforts such as Open X-Embodiment [@o2024open] and DROID [@khazatsky2024droid] pool data across diverse kinematics to train generalizable, cross-embodiment behavioral policies. Simultaneously, in the structured time-series domain, models such as Chronos [@ansari2024chronos], TimesFM [@das2023decoder], Moirai [@woo2024unified], MOMENT [@pmlr-v235-goswami24a], Timer [@liu2024timer], Lag-Llama [@rasul2023lag], and TabPFN-TS [@hoo2025tables] leverage pretraining corpora to yield powerful zero-shot forecasters. However, because these TS-FMs are predominantly trained on web-scraped, financial, or ecological data, we hypothesize that they lack grounding in physical actuation and may struggle to disentangle static payload biases from actual dynamic behavior in industrial settings. FactoryNet is designed as a bridge between these two tracks: an industrial-scale, control-theoretically structured corpus for training and evaluating TS-FMs on complex dynamics across embodiments.

## Physics-Informed and Structured Dynamics

In parallel to data-driven forecasting, Physics-Informed Neural Networks (PINNs) [@RAISSI2019686] and grey-box models incorporate known governing equations into the learning process. While these approaches excel in scenarios with well-defined partial differential equations, applying them to complex multi-joint robotic systems often requires residual-dynamics learning [@zeng2020tossingbot] or structured priors. FactoryNet complements this literature by providing the empirical Setpoint-Effort-Feedback decomposition required to train and evaluate structured or physics-inspired models at scale.

# The FactoryNet Dataset

FactoryNet v1.0 is the largest open-source industrial-robot time-series dataset containing labelled anomalies and organized around a control-theoretic schema. It comprises three pillars: real-world laboratory recordings, standardized open-source adaptations, and a synthetic generation pipeline. Because industrial data is sampled at high frequencies across many joints and sensors, 23k episodes yield a high-density, continuous corpus of the kind required to learn complex physical dynamics.

## Dataset Composition

As detailed in Table `\ref{tab:dataset_composition}`{=latex} and Figure `\ref{fig:dataset_overview}`{=latex}, the corpus encompasses multiple data streams. The laboratory track consists of novel recordings we collected from UR3 and KUKA KR10 industrial robotic arms executing three complex tasks: Pick & Place, Screwdriving, and Peg-in-Hole. We ingested and restructured existing high-quality open-source datasets (voraus-AD, AURSAD, and UMich CNC [@sharon_2017_toolwear]) into our unified schema. The dataset is structured using a hierarchical taxonomy grounded in the IEC 81346 standard for industrial systems, allowing the schema to seamlessly integrate diverse modalities such as CNC milling centres and rotating machinery. A parallel synthetic track generated via NVIDIA Isaac Sim provides procedurally scaled data for model pretraining.

```{=latex}
\resizebox{\columnwidth}{!}{%
        \small
        \begin{tabular}{llccrr}
            \toprule
            \textbf{Source}         & \textbf{Machine}     & \textbf{Tasks}
                                    & \textbf{Faults}      & \textbf{Episodes}
                                    & \textbf{Datapoints}                            \\
            \midrule
            \textbf{Our Lab (Real)} & UR3                  & P\&P, Screw, Peg  & Yes
                                    & 7,141                & 18M                     \\
            \textbf{Our Lab (Real)} & KUKA KR10            & P\&P              & Yes
                                    & 1,973                & 4M                      \\
            \midrule
            \textbf{Open (Real)}    & voraus-AD (Yu-Cobot) & P\&P              & Yes
                                    & 2,122                & 16M                     \\
            \textbf{Open (Real)}    & AURSAD (UR3e)        & Screw             & Yes
                                    & 2,045                & 3M                      \\
            \textbf{Open (Real)}    & UMich CNC            & Machining         & Yes
                                    & 18                   & 18K                     \\
            \midrule
            \textbf{Synthetic}      & Isaac Sim (UR5)      & P\&P              & No
                                    & 9,799                & 10M                     \\
            \bottomrule
        \end{tabular}%
    }
```
```{=latex}
\begin{figure*}[t]

    \begin{tikzpicture}[
            node distance=1cm and 3cm,
            box/.style={draw, rectangle, minimum width=3cm, minimum height=0.8cm, align=center, font=\small, rounded corners=2pt},
            header/.style={font=\small\bfseries, align=center},
            arrow/.style={-Latex, thick, draw=black!60}
        ]
        \node[header] (h1) at (0,0) {Data Source};
        \node[header] (h2) at (4.5,0) {Embodiment};
        \node[header] (h3) at (9,0) {Target Task};
        \node[box] (src1) [below=0.5cm of h1] {Our Lab (Real)\\9,114 Eps.};
        \node[box, text width=3.2cm] (src2) [below=1.5cm of src1] {voraus-AD, AURSAD,\\UMich CNC (Real)\\4,185 Eps.};
        \node[box] (src3) [below=1.5cm of src2] {Isaac Sim (Synthetic)\\9,799 Eps.};
        \node[box] (emb1) [below=0.5cm of h2] {UR3(e)\\9,186 Eps.};
        \node[box] (emb2) [below=0.2cm of emb1] {KUKA KR10\\1,973 Eps.};
        \node[box] (emb3) [below=0.2cm of emb2] {Yu-Cobot\\2,122 Eps.};
        \node[box] (emb4) [below=0.2cm of emb3] {CNC Gantry\\18 Eps.};
        \node[box] (emb5) [below=0.2cm of emb4] {UR5\\9,799 Eps.};
        \node[box] (tsk1) [below=0.5cm of h3] {Pick \& Place\\18,293 Eps.};
        \node[box] (tsk2) [below=0.4cm of tsk1] {Screwdriving\\3,165 Eps.};
        \node[box] (tsk3) [below=0.4cm of tsk2] {Peg-in-Hole\\1,622 Eps.};
        \node[box] (tsk4) [below=0.4cm of tsk3] {Machining\\18 Eps.};
        \draw[arrow] (src1.east) -- (emb1.west);
        \draw[arrow] (src1.east) -- (emb2.west);
        \draw[arrow] (src2.east) -- (emb1.west);
        \draw[arrow] (src2.east) -- (emb3.west);
        \draw[arrow] (src2.east) -- (emb4.west);
        \draw[arrow] (src3.east) -- (emb5.west);
        \draw[arrow] (emb1.east) -- (tsk1.west);
        \draw[arrow] (emb1.east) -- (tsk2.west);
        \draw[arrow] (emb1.east) -- (tsk3.west);
        \draw[arrow] (emb2.east) -- (tsk1.west);
        \draw[arrow] (emb3.east) -- (tsk1.west);
        \draw[arrow] (emb4.east) -- (tsk4.west);
        \draw[arrow] (emb5.east) -- (tsk1.west);
    \end{tikzpicture}
    \caption{\textbf{The FactoryNet Dataset.} A structured overview of the corpus composition illustrating the mapping of 23k task executions. The dataset aggregates real-world laboratory recordings, standardized open-source subsets, and synthetic generations into a unified pretraining substrate covering four distinct actuation tasks.}
    \label{fig:dataset_overview}
\end{figure*}
```
## The S-E-F-C Signal Taxonomy: A Unified Vocabulary

The defining feature of FactoryNet is its control-theoretic structure. Most existing benchmarks simply log raw sensor streams, intrinsically tangling the controller's target variables with the machine's actual physical execution. This conflates cause and effect while suffering from vendor-specific naming conventions.

To resolve this, we employ embodiment-specific adapter scripts to programmatically map over 300 heterogeneous data columns into four standardized roles (machine-readable tables: Appendix `\ref{app:sefc_mapping}`{=latex}). These categories are: **Setpoint (S)** (commanded intent, e.g., target joint positions), **Effort (E)** (actuation energy expended, e.g., motor current/torque), **Feedback (F)** (measured physical outcome, e.g., actual positions), and **Context (C)** (environmental or static variables, e.g., payload mass).

This taxonomy allows a single dataloader to work across UR3, KUKA KR10, and CNC machinery: a 6-DOF rotational arm and a 4-axis CNC gantry expose the same four roles, only with different axis counts and units. By enforcing this taxonomy, S-E-F-C acts as a unified vocabulary for cross-embodiment models, providing a principled inductive bias for learning the difference between expected dynamics and external disturbances. Signal availability varies by embodiment: KUKA KR10 (KSS 8.3) does not expose joint velocities, commanded TCP pose, or TCP force/torque via its RSI interface; these channels are marked absent in the S-E-F-C mapping (Appendix `\ref{app:sefc_mapping}`{=latex}).

## Synthetic Pipeline and Sim-to-Real

To reduce dependence on real-only data, FactoryNet includes a synthetic pipeline in NVIDIA Isaac Sim with procedural generation and domain randomization (mass, friction, controller gains), yielding 9799 Pick & Place episodes with aligned S-E-F-C metadata and matched healthy twins for controlled fault-deviation analysis. To ensure the synthetic pretraining corpus captures robust physical dynamics and helps bridge the sim-to-real gap, we employ extensive domain randomization across the procedurally generated UR5 Pick & Place episodes in NVIDIA Isaac Sim.

-   **Mass Randomization:** The payload (cube) mass is uniformly sampled per episode between $0.10$ and $0.30$ kg (with broader exploratory configurations allowing up to $0.80$ kg). Robot link masses remain fixed to isolate payload-driven dynamic variations and ensure baseline kinematic stability.

-   **Surface Friction:** We randomize the general Coulomb friction coefficient of the target object between $0.30$ and $0.50$ per episode. The end-effector gripper pad maintains a fixed, high-friction coefficient of $1.2$ to ensure stable grasps once contact is successfully established.

-   **Controller Gains:** To simulate variations in actuation force and mechanical compliance at the end-effector, the proportional gain ($K_p$) of the gripper is randomized uniformly in the range of $[5000.0, 12000.0]$. The UR5 arm's main joint PID controllers remain fixed to nominal values.

-   **Sensor Noise Model:** We inject artificial Gaussian noise into the simulated telemetry to mimic real-world sensor degradation, encoder quantization, and signal noise. Using a base standard deviation of $\sigma_{\text{base}} = 0.002$, noise is scaled across modalities: joint positions ($\sigma = 0.002$ rad), joint velocities ($\sigma = 0.02$ rad/s), and joint efforts/torques ($\sigma = 0.1$). Additionally, spatial perception noise is applied to the object's tracked state ($\sigma_{xy} = 0.002$ m, $\sigma_z = 0.001$ m).

-   **Task and Geometric Variation:** The task features procedural geometric and spatial variations to prevent policy overfitting. The target cube's physical dimensions (width, depth, and height) are independently randomized within specified bounds for every episode. Furthermore, the object's initial spawn position on the conveyor is continuously randomized within an $8 \times 8$ cm ($0.08$ m) bounding box relative to the nominal pick center.

-   **Simulation Dynamics:** The internal physics simulation engine operates at a fixed temporal step size of $\Delta t \approx 0.016667$ s (60 Hz). To align this synthetic track with the 100 Hz standard utilized by the physical laboratory recordings (see Section 3), the raw 60 Hz simulation telemetry undergoes temporal interpolation during the data ingestion pipeline.

Batch sim-to-real validation (pairing real and simulated episodes under the same RTDE-shaped schema, phase-aware gap metrics) is reported in Section `\ref{sec:sim2real_gap}`{=latex}.

## Batch sim-to-real validation {#sec:sim2real_gap}

We run sim2real rollouts in Isaac Sim 4.5.0 (headless Docker, PhysX) using the built-in UR3 USD asset and a position-control stack (`ArticulationAction`) with phase-consistent waypoint replay from real `target_joint_*` signals. The task is UR3 pick-and-place with a 10-phase structure (`above_pick` to `return`). Simulation steps at 240 Hz and logs at 10 Hz. Real episodes are exported from FactoryWave parquet to per-episode RTDE-shaped CSVs, converted to per-episode simulation configs, replayed in Isaac, and paired by episode ID/filename. Simulated logs preserve FactoryWave-compatible fields (`joint_*`, `target_joint_*`, `joint_current_*`, `tcp_*`, `task_phase`, and status/context fields). Gap metrics are computed phase-wise with time normalization/interpolation. Results of the gap analysis are shown in Table `\ref{tab:sim2real_batch_gap}`{=latex}.

```{=latex}
\resizebox{\columnwidth}{!}{%
        \begin{tabular}{lrrrr}
            \toprule
            Metric                 & Mean  & Median & P10   & P90   \\
            \midrule
            Joint RMSE (deg)       & 3.65  & 2.83   & 1.93  & 5.12  \\
            TCP position RMSE (mm) & 13.16 & 13.26  & 8.87  & 16.92 \\
            EE L2 RMS (mm)         & 25.11 & 25.17  & 16.96 & 32.58 \\
            TCP rotvec RMSE (mrad) & 1877  & 2605   & 8.75  & 3136  \\
            W1 effort mean (A)     & 0.83  & 0.81   & 0.77  & 0.91  \\
            \bottomrule
        \end{tabular}%
    }
```
An important source of residual pose discrepancy is end-effector mismatch: the Isaac setup used a Robotiq 2FG85-style gripper configuration, whereas the real FactoryWave episodes used an OnRobot 2FG14 gripper. Differences in tool geometry/TCP definition and mounting can bias absolute TCP and orientation metrics. We therefore interpret remaining TCP rotation spread conservatively and treat gripper-accurate tool calibration as future work.

## Faults and Anomalies

To support anomaly detection and robust control research, of the 9,114 lab episodes, approximately 40% are healthy and 60% contain injected faults across 27 anomaly types spanning three tasks: **Pick & Place**, **Screwdriving**, and **Peg-in-Hole**.

## Data Accessibility and Licensing

Novel laboratory and synthetic data are released under the MIT license; adapted open-source subsets retain their original licenses (CC-BY 4.0 or equivalent). The repository provides S-E-F-C Parquet files, metadata, and framework-native dataloaders at <https://huggingface.co/datasets/Forgis/FactoryNet>.

# Dataset Utility & Validation

To demonstrate that FactoryNet provides a viable substrate for both single-machine modelling and foundation model pretraining, we evaluate the dataset across standard industrial baselines and establish the open challenge of cross-embodiment transfer.

`\noindent`{=latex}**Evaluation Protocol.** Evaluation protocols are task-specific. For voraus-AD anomaly detection, we follow the official protocol of @Brockmann2023TheVD: training on 948 healthy episodes only, and testing on the 1,174-episode labelled set (419 healthy + 755 anomalous). In contrast, the TCN-Transformer forecasting experiments utilize a separate pretraining split (1,093 training / 137 validation, randomly sampled from all healthy episodes) to maximize observed dynamics. Confidence intervals for our S-E-F-C MLP are 95% bootstrap CIs computed over 1,000 resamplings of episode-level anomaly scores; CIs for unstructured baselines are reported as standard deviation across fault categories as published in @Brockmann2023TheVD.

## Model architectures and training {#sec:exp_details}

**Anomaly Detection: MLP Architecture.** The S-E-F-C MLP is a supervised regressor trained to predict motor torque from setpoint signals. **Inputs:** 18 Setpoint signals (`setpoint_pos_0…5`, `setpoint_vel_0…5`, `setpoint_acc_0…5`). **Outputs:** 6 Effort signals (`effort_motor_torque_0…5`). **Anomaly score:** per-episode mean absolute error (MAE) between predicted and true motor torque---higher error indicates anomaly. To maintain parity with standard anomaly detection protocols, the model is trained on healthy episodes only (948 episodes from voraus-AD).

**Architecture:** The network is constructed with three hidden layers consisting of 512, 256, and 128 units, respectively. We apply the Rectified Linear Unit (ReLU) activation function after each hidden layer. Dropout is not utilized in this architecture.

**Training Details:** The model is optimized using Adam (`torch.optim.Adam`) with an initial learning rate of $5 \times 10^{-4}$, a weight decay ($L_2$ penalty) of $1 \times 10^{-5}$, and a batch size of 4,096. The learning rate is decayed following a cosine annealing schedule. Models are trained for a maximum of 500 epochs, utilizing an early stopping criterion that halts training if the validation loss fails to improve for 30 consecutive epochs.

**TCN-Transformer Architecture and Training.** The TCN-Transformer comprises a 3-layer dilated Temporal Convolutional Network (kernel size 3) for local feature extraction, followed by a 2-layer Transformer encoder (4 attention heads, hidden dimension 64, feedforward dimension 128) for sequence modelling. The total parameter count is approximately 105,000. Training was conducted using the AdamW optimizer (learning rate $1\times10^{-4}$) for 100 epochs. *(Note: Due to the reduced parameter count, training is highly efficient on standard hardware.)*

The model predicts joint acceleration; Euler integration ($\Delta t =
    0.01$ s) yields position and velocity. Survival steps are computed as the first step at which per-joint position error exceeds 0.01 rad, averaged across all test episodes and joints.

For the anomaly detection evaluation (Table `\ref{tab:anomaly_baselines}`{=latex}), all unstructured baselines (1-NN, PCA, GANF, CAE, LSTM-VAE, HMM, and MVT-Flow) utilize the exact architectures and hyperparameters established in the original voraus-AD benchmark [@Brockmann2023TheVD].

For the multi-step forecasting and zero-shot transfer evaluations (Tables `\ref{tab:forecasting_metrics}`{=latex} and `\ref{tab:mean_centered}`{=latex}), we evaluate our model against four baseline forward-dynamics predictors. All trainable baselines utilize the identical 10-step context window to predict 1-step-ahead joint accelerations, which are subsequently integrated.

**Training Details:** All trainable forecasting baselines (Linear, Flat MLP, TCN) were trained on the exact same 1,093-episode pretraining split as the main TCN-Transformer model. They were trained to minimize Mean Squared Error (MSE) on the predicted joint accelerations using the Adam optimizer.

-   **Linear Baseline:** A standard linear regression model consisting of a single `nn.Linear` layer that maps the flattened context window ($10 \text{ steps} \times 36 \text{ features} = 360 \text{ inputs}$) directly to the target acceleration space.

-   **Flat MLP:** A multi-layer perceptron utilizing two hidden layers (128 units and 64 units, respectively) with ReLU activation functions, mapping the flattened context window to the target predictions.

-   **TCN Baseline:** A 2-layer Temporal Convolutional Network (`Conv1d`) utilizing a kernel size of 3 and a hidden dimension of 64. This serves as a representative pre-2023 benchmark for sequence modeling on industrial control data.

-   **Kinematic Baseline (Zero-Predictor):** A non-learned, naive physics baseline that constantly predicts zero acceleration. It assumes the robot maintains constant velocity from the final observation step, generating its trajectory purely through the kinematic integrator.

## Single-Machine Baselines: Validating the S-E-F-C Schema

**Anomaly Detection.** We use voraus-AD to test whether S-E-F-C enables competitive anomaly detection via supervised dynamics rather than holistic reconstruction. Unstructured baselines reconstruct all 130 channels end-to-end; our **S-E-F-C MLP** is a regressor on 24 signals, mapping 18 Setpoints (`setpoint_pos_0…5`, `setpoint_vel_0…5`, `setpoint_acc_0…5`) to 6 Efforts (`effort_motor_torque_0…5`). Per-episode MAE on Effort is the anomaly score. On 24 signals alone it reaches **83.2%** mean AUROC. Table `\ref{tab:anomaly_baselines}`{=latex} shows it beats weaker full-channel baselines (1-NN, GANF, PCA) but not the strongest ones (CAE, LSTM-VAE, MVT-Flow). Architectures follow @Brockmann2023TheVD.

```{=latex}
\footnotesize
```
`\setlength{\tabcolsep}{4.5pt}`{=latex}

::: {#tab:anomaly_baselines}
  **Method**                  **Input Channels**           **Mean AUROC**
  -------------------------- -------------------- ---------------------------------
  MLP - All signals (Ours)           130             69.1 $\pm$ 3.1$^{\ddagger}$
  1-NN                               130                        77.5
  GANF                               130            79.9 $\pm$ 12.7$^{\ddagger}$
  PCA                                130                        80.0
  **S-E-F-C MLP (Ours)**            **24**         **83.2 $\pm$ 9.6$^{\ddagger}$**
  CAE                                130             85.2 $\pm$ 9.2$^{\ddagger}$
  LSTM-VAE                           130            86.7 $\pm$ 10.1$^{\ddagger}$
  HMM                                130             87.4 $\pm$ 5.8$^{\ddagger}$
  MVT-Flow                           130             93.6 $\pm$ 5.7$^{\ddagger}$

  : Mean AUROC on voraus-AD. Baselines: 130 channels; ours: 24 (Setpoint$\to$Effort). Values from @Brockmann2023TheVD. $^{\ddagger}$Std across 12 fault categories.
:::

```{=latex}
\normalsize
```
Table `\ref{tab:per_category_auroc}`{=latex} reports per-category AUROC on the voraus-AD subset for all seven methods compared in the main paper. The S-E-F-C MLP achieves the highest AUROC on mechanically distinctive faults (Miscommutation: 99.2, Additional Axis Weight: 95.8) where sustained Effort--Feedback divergence provides a strong discriminative signal, but struggles on transient or subtle gripping failures (Collision w/ Cables: 67.6, Losing Can: 71.8) where the anomaly window is brief and the single-step MLP lacks temporal modelling capacity.

```{=latex}
\begin{table*}[t]

    \caption{Per-category anomaly detection AUROC on voraus-AD.
        Unstructured baselines use 130 signals; S-E-F-C MLP uses only 24 signals.
        $N$ = number of anomalous episodes per category.
        $^{\dagger}$\,95\% bootstrap CI over episodes for S-E-F-C MLP; $^{\ddagger}$\,standard deviation across fault categories for other methods (from \citet{Brockmann2023TheVD}).}
    \label{tab:per_category_auroc}
    \resizebox{\textwidth}{!}{%
        \begin{tabular}{lrcccccccc}
            \toprule
            \textbf{Fault Category} & \textbf{$N$}
                                    & \textbf{1-NN}                           & \textbf{PCA}
                                    & \textbf{GANF}                           & \textbf{CAE}
                                    & \textbf{LSTM-VAE}                       & \textbf{HMM}
                                    & \textbf{MVT-Flow}
                                    & \textbf{S-E-F-C MLP (Ours)}                                                                                                                                                  \\
            \midrule
            Additional friction     & 144                                     & 74.8         & 76.4  & $88.5_{\pm4.5}$  & $89.4_{\pm0.2}$  & $88.7_{\pm1.5}$  & $88.0_{\pm0.7}$ & $96.6_{\pm0.6}$  & 80.0          \\
            Miscommutation          & 89                                      & 80.8         & 87.0  & $98.8_{\pm1.1}$  & $99.1_{\pm0.0}$  & $98.1_{\pm0.5}$  & $93.7_{\pm1.3}$ & $99.8_{\pm0.3}$  & 99.2          \\
            Misgrip can             & 11                                      & 100.0        & 100.0 & $47.6_{\pm13.1}$ & $100.0_{\pm0.0}$ & $100.0_{\pm0.0}$ & $71.0_{\pm3.3}$ & $95.3_{\pm3.3}$  & 83.8          \\
            Losing can              & 74                                      & 68.7         & 70.1  & $72.1_{\pm5.8}$  & $72.6_{\pm0.3}$  & $70.4_{\pm2.9}$  & $88.8_{\pm1.0}$ & $96.2_{\pm0.4}$  & 71.8          \\
            Add.\ axis weight       & 156                                     & 75.0         & 79.2  & $93.2_{\pm2.4}$  & $93.5_{\pm0.1}$  & $82.7_{\pm1.1}$  & $89.6_{\pm1.2}$ & $94.1_{\pm0.7}$  & \textbf{95.8} \\
            Collision w/ foam       & 72                                      & 69.6         & 73.9  & $81.2_{\pm6.2}$  & $81.5_{\pm0.2}$  & $81.5_{\pm2.1}$  & $89.8_{\pm1.5}$ & $87.5_{\pm1.2}$  & 74.7          \\
            Collision w/ cables     & 48                                      & 74.5         & 75.7  & $82.7_{\pm6.4}$  & $79.6_{\pm0.3}$  & $77.3_{\pm3.6}$  & $91.8_{\pm1.4}$ & $84.7_{\pm1.2}$  & 67.6          \\
            Collision w/ cardboard  & 22                                      & 82.8         & 83.6  & $77.5_{\pm5.8}$  & $78.6_{\pm0.3}$  & $82.8_{\pm4.8}$  & $86.3_{\pm1.2}$ & $88.3_{\pm1.2}$  & 76.7          \\
            Varying can weight      & 80                                      & 63.7         & 64.2  & $68.9_{\pm8.7}$  & $72.3_{\pm0.3}$  & $71.4_{\pm2.1}$  & $90.9_{\pm2.0}$ & $85.1_{\pm1.1}$  & 76.2          \\
            Cable at robot          & 10                                      & 63.0         & 71.6  & $76.6_{\pm8.1}$  & $83.1_{\pm0.3}$  & $96.0_{\pm1.4}$  & $84.4_{\pm1.1}$ & $100.0_{\pm0.0}$ & 91.3          \\
            Invalid gripping pos.   & 12                                      & 93.4         & 92.1  & $86.6_{\pm10.8}$ & $88.8_{\pm0.3}$  & $97.7_{\pm1.3}$  & $91.8_{\pm1.4}$ & $100.0_{\pm0.0}$ & 89.1          \\
            Unstable platform       & 37                                      & 83.6         & 85.9  & $84.6_{\pm3.8}$  & $83.9_{\pm0.2}$  & $93.6_{\pm1.9}$  & $82.5_{\pm1.2}$ & $96.1_{\pm0.7}$  & 92.8          \\
            \midrule
            \textbf{Mean}           & 755                                     & 77.5         & 80.0
                                    & $79.9_{\pm12.7}{}^\ddagger$
                                    & $85.2_{\pm9.2}{}^\ddagger$
                                    & $86.7_{\pm10.1}{}^\ddagger$
                                    & $87.4_{\pm5.8}{}^\ddagger$
                                    & $93.6_{\pm5.7}{}^\ddagger$
                                    & \textbf{83.2 [81.5,\,86.1]$^{\dagger}$}                                                                                                                                      \\
            \bottomrule
        \end{tabular}%
    }
\end{table*}
```
**Multi-Step Forecasting.** To demonstrate support for high-fidelity dynamics modelling, we evaluate an autoregressive TCN-Transformer (105k parameters) on the voraus-AD Pick & Place data. Operating strictly on S-E-F-C inputs, the model acts as a forward-dynamics predictor: it forecasts 1-step-ahead joint accelerations via a 10-step context window, which are integrated (Euler, $\Delta t = 0.01$ s) to derive position and velocity. Models are trained on 1,093 normal episodes and validated on 137 held-out normal episodes. Full architecture and training hyperparameters are detailed in Section `\ref{sec:exp_details}`{=latex}.

As shown in Figure `\ref{fig:forecasting}`{=latex} and Table `\ref{tab:forecasting_metrics}`{=latex} (Appendix `\ref{app:forecasting}`{=latex}), the TCN-Transformer achieves an average of **156.7 steps** (78.4% of the 200-step horizon at 100 Hz) without exceeding a strict 0.01 rad per-joint position error threshold, substantially outperforming all baselines. At 200 steps the TCN-Transformer's MSE ($0.11 \times 10^{-4}$ rad$^2$) is more than four orders of magnitude below the next best baseline.

![Multi-step forecasting on the voraus-AD (Yu-Cobot) Pick & Place task. The TCN-Transformer maintains predictive accuracy within the 0.01 rad threshold for an average of 156.7 steps (78.4% of the 200-step horizon at 100 Hz), substantially outperforming all baselines on in-domain dynamics prediction.](figures/aursad_forecasting.png){#fig:forecasting width="\\columnwidth"}

## Cross-Embodiment Transfer: An Open Challenge

The S-E-F-C schema enables structured zero-shot transfer across machine types. To evaluate this, we define the *mean-centered MAE* (MC-MAE) metric. By subtracting the per-episode, per-joint mean from both the ground truth and predictions prior to computing the absolute error, MC-MAE explicitly isolates dynamic forces from static payload biases.

A TCN-Transformer trained solely on voraus-AD (Yu-Cobot) Pick & Place data achieves a mean-centered MAE of **0.339 $\pm$ 0.006** on 1,433 AURSAD (UR3e) Screwdriving episodes, outperforming every baseline including the kinematic baseline ($0.373 \pm 0.005$) and all structureless learned models (Table `\ref{tab:mean_centered}`{=latex}). Raw effort-MAE remains high (1.74 vs. 1.51 for a zero-predictor) due to static payload and gravity-compensation differences between embodiments, but MC-MAE confirms that the *shape* of the dynamics transfers successfully across machines.

```{=latex}
\resizebox{0.95\columnwidth}{!}{%
        \begin{tabular}{lcc}
            \toprule
            \textbf{Model}                  & \textbf{MC-MAE} & \textbf{95\% CI ($\pm$)} \\
            \midrule
            Linear                          & 0.928           & 0.023                    \\
            Flat MLP                        & 0.792           & 0.019                    \\
            TCN                             & 0.770           & 0.017                    \\
            Kinematic Baseline              & 0.373           & 0.005                    \\
            \textbf{TCN-Transformer (Ours)} & \textbf{0.339}  & \textbf{0.006}           \\
            \bottomrule
        \end{tabular}%
    }
```
# Conclusion & Limitations

FactoryNet provides the largest open-source, fault-injected time-series corpus for industrial robotics, unified by the S-E-F-C taxonomy. Our experiments show that the schema enables competitive anomaly detection with 5$\times$ fewer signals, accurate multi-step dynamics forecasting, and positive zero-shot cross-embodiment transfer. The sim-to-real gaps we quantify are naturally interpreted as errors of learned *forward* dynamics under S--E--F--C-aligned inputs, not merely covariate shift in raw telemetry. Current limitations include synthetic data restricted to Pick & Place and cross-embodiment transfer evaluated on a single source-target pair; future work will expand to additional machine families, tasks, and transfer settings.

```{=latex}
\clearpage
```
```{=latex}
\bibliographystyle{icml2026}
```
```{=latex}
\newpage
```
```{=latex}
\appendix
```
```{=latex}
\onecolumn
```
﻿

# Datasheet for Datasets (Gebru et al., 2021) {#app:datasheet}

Following the recommendations of @gebru2021datasheets, we provide a structured datasheet for FactoryNet v1.0 (`\cref{tab:datasheet}`{=latex}).

```{=latex}
\small
```
::: {#tab:datasheet}
  **Question**                              **Answer**
  ----------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  *Motivation*
  Purpose                                   Pretraining substrate for industrial time-series foundation models, anomaly detection benchmarking, and cross-embodiment transfer research.
  Creators                                  Karim Othman (Forgis), Jonas Petersen (ETH Zurich / Forgis), Matei Ignuta-Ciuncanu (Imperial College / UC Berkeley), Camilla Mazzoleni (Forgis), Federico Martelli (ETH Zurich / Forgis), Alessandro Lombardi (Forgis), Riccardo Maggioni (Forgis), Philipp Petersen (University of Vienna).
  Funding                                   Fully funded by Forgis AG.
  *Composition*
  Instances                                 Episodes of robotic task execution, each containing multi-channel time-series at 100 Hz with S-E-F-C role annotations.
  Count                                     23,098 episodes total: 7,141 real lab (UR3), 1,973 real lab (KUKA KR10), 4,185 open-source (voraus-AD 2,122; AURSAD (UR3e) 2,045; UMich CNC 18), 9,799 synthetic (Isaac Sim UR5).
  Sampling                                  Lab data: programmatic task execution with configurable fault injection (40% healthy, 60% anomalous). Open-source: full datasets ingested. Synthetic: procedural generation with domain randomization.
  Missing data                              Sensor dropouts $<$`<!-- -->`{=html}0.1% of time steps; handled via linear interpolation. No episodes removed due to missing data.
  Confidentiality                           No PII. Industrial parameters only (joint angles, torques, velocities).
  *Collection Process*
  Acquisition                               Lab episodes recorded by the authors via robot controller APIs (RTDE for UR3, RSI for KUKA KR10) at 100 Hz. Open-source subsets downloaded and re-processed into S-E-F-C format via adapter scripts.
  Mechanisms                                Automated scripts executing task programs with fault injection at configurable rates. 27 anomaly types injected programmatically (payload variation, misgrips, collisions, stripped threads, jamming, friction changes, etc.).
  Who collected                             Karim Othman, Jonas Petersen, Camilla Mazzoleni, Federico Martelli, Alessandro Lombardi, Riccardo Maggioni (Forgis / ETH Zurich).
  Time frame                                March 1 -- April 20, 2026.
  Ethical review                            N/A --- no human subjects.
  *Preprocessing, Cleaning, and Labeling*
  Preprocessing                             Resampling to 100 Hz, NaN interpolation, S-E-F-C column mapping per source via adapter scripts. No per-channel normalisation applied (raw physical units preserved).
  Raw data                                  Raw recordings available on request. Distributed format: S-E-F-C Parquet files with metadata.
  Labeling                                  Programmatic fault injection with known ground truth; no manual annotation required for lab data. Open-source subsets retain original labels, mapped to unified anomaly taxonomy.
  *Uses*
  Prior uses                                Anomaly detection baselines (this paper), cross-embodiment transfer experiments (this paper).
  Other uses                                Forecasting, remaining useful life estimation, control policy learning, sim-to-real benchmarking, counterfactual analysis.
  Misuse potential                          Dataset reflects specific robot models and lab conditions; generalisation claims to unseen embodiments or industrial deployments should be scoped accordingly.
  *Distribution*
  Distribution                              Available on HuggingFace at <https://huggingface.co/datasets/Forgis/FactoryNet>.
  License                                   Novel lab and synthetic data under MIT. Open-source subsets retain original licenses (CC-BY 4.0 or equivalent).
  Restrictions                              None. No export controls apply.
  *Maintenance*
  Maintainer                                Forgis AG. Issue tracker: GitHub repository.
  Updates                                   Semantic versioning (v1.0 at submission). New embodiments and tasks increment minor version; schema changes increment major version. Prior versions remain available.
  Retention                                 All versions permanently hosted on HuggingFace.
  Errata                                    Reported and tracked via GitHub issues; corrections published as patch versions.

  : Datasheet for FactoryNet v1.0.
:::

# Signal-to-S-E-F-C Mapping {#app:sefc_mapping}

We provide one table per source mapping raw signal names to S-E-F-C roles. UR3, KUKA KR10 and Isaac Sim mappings are listed with raw signal names confirmed; CNC, AURSAD, and voraus-AD mappings are fully confirmed.

## B.1`\quad `{=latex}UR3 Laboratory Source {#b.1ur3-laboratory-source .unnumbered}

Signals of UR3 can be found at Table  `\ref{tab:sefc_mapping_ur3e}`{=latex}

```{=latex}
\footnotesize
```
::: {#tab:sefc_mapping_ur3e}
  **Raw Signal Name**                           **S-E-F-C Role**   **Unit**                  **Notes**
  --------------------------------------------- ------------------ ------------------------- -----------------------------
  `machine_id`                                  Metadata           ---                       Episode metadata
  `ur3_robot_target_joint_0…5`                  Setpoint           rad                       6 joints
  `ur3_robot_target_joint_vel_0…5`              Setpoint           rad/s                     6 joints
  `ur3_robot_joint_0…5`                         Feedback           rad                       Actual positions, 6 joints
  `ur3_robot_joint_vel_0…5`                     Feedback           rad/s                     Actual velocities, 6 joints
  `ur3_robot_joint_current_0…5`                 Effort             A                         6 joints
  `ur3_robot_target_joint_current_0…5`          Setpoint           A                         6 joints
  `ur3_robot_joint_temp_0…5`                    Context            `\textdegree `{=latex}C   6 joints
  `ur3_robot_joint_control_output_0…5`          Effort             ---                       6 joints
  `ur3_robot_joint_mode_0…5`                    Context            enum                      6 joints
  `ur3_robot_tcp_x/y/z`                         Feedback           m                         Actual TCP position
  `ur3_robot_tcp_rx/ry/rz`                      Feedback           rad                       Actual TCP orientation
  `ur3_robot_target_tcp_x/y/z`                  Setpoint           m                         Target TCP position
  `ur3_robot_target_tcp_rx/ry/rz`               Setpoint           rad                       Target TCP orientation
  `ur3_robot_tcp_speed_x/y/z/rx/ry/rz`          Feedback           m/s & rad/s               Actual TCP speed (6 axes)
  `ur3_robot_target_tcp_speed_x/y/z/rx/ry/rz`   Setpoint           m/s & rad/s               Target TCP speed (6 axes)
  `ur3_robot_tcp_force_x/y/z`                   Effort             N                         TCP force
  `ur3_robot_tcp_torque_x/y/z`                  Effort             Nm                        TCP torque
  `ur3_robot_robot_mode`                        Context            enum                      Enum
  `ur3_robot_safety_mode`                       Context            enum                      Enum
  `ur3_robot_digital_inputs`                    Context            bitmask                   Bitmask
  `ur3_robot_digital_outputs`                   Context            bitmask                   Bitmask
  `ur3_robot_robot_status`                      Context            enum
  `ur3_robot_safety_status`                     Context            enum
  `ur3_robot_runtime_state`                     Context            enum
  `ur3_robot_main_voltage`                      Context            V                         V
  `ur3_robot_robot_voltage`                     Context            V                         V
  `ur3_robot_robot_current`                     Context            A                         A
  `ur3_robot_analog_input_0/1`                  Context            V/A
  `ur3_robot_analog_output_0/1`                 Context            V/A
  `ur3_robot_speed_scaling`                     Context            \%
  `ur3_robot_target_speed_fraction`             Context            \%
  `ur3_robot_momentum`                          Context            kg$\cdot$m/s
  `realsense_camera_frame_count`                Context            count
  `realsense_camera_connected`                  Context            bool
  `realsense_camera_streaming`                  Context            bool

  : S-E-F-C mapping for the UR3 laboratory source.
:::

## B.2`\quad `{=latex}KUKA KR10 Laboratory Source {#b.2kuka-kr10-laboratory-source .unnumbered}

Signals of KUKA KR10 can be found at Table  `\ref{tab:sefc_mapping_kuka}`{=latex}

```{=latex}
\resizebox{\textwidth}{!}{%
        \begin{tabular}{llll}
            \toprule
            \textbf{Signal Group} & \textbf{Described Fields}              & \textbf{S-E-F-C Role} & \textbf{Unit} \\
            \midrule
            Position (actual)     & Actual joint positions ($\times$6)     & Feedback              & degrees       \\
            Position (commanded)  & Commanded joint positions ($\times$6)  & Setpoint              & degrees       \\
            TCP pose (actual)     & Actual TCP pose ($\times$6)            & Feedback              & mm / degrees  \\
            Motor current         & Motor current per axis ($\times$6)     & Effort                & \% of max     \\
            Motor torque          & Motor torque per axis ($\times$6)      & Effort                & Nm            \\
            Motor temperature     & Motor temperature per axis ($\times$6) & Context               & Kelvin        \\
            Cartesian accel.      & Accel.\ X, Y, Z, abs ($\times$4)       & Feedback              & m/s$^2$       \\
            Speed override        & Speed override (scalar)                & Context               & \%            \\
            Process state         & State enum (FREE/ACTIVE/STOP/END)      & Context               & enum          \\
            Digital I/O           & Digital inputs bitmask                 & Context               & bitmask       \\
            Digital I/O           & Digital outputs bitmask                & Context               & bitmask       \\
            \midrule
            \textit{Not available on KSS 8.3: joint velocities, commanded TCP
                    pose, TCP force/torque, joint voltage, tool accelerometer, joint control output.}             \\
            \bottomrule
        \end{tabular}%
    }
```
## B.3`\quad `{=latex}UMich CNC Source {#b.3umich-cnc-source .unnumbered}

Mapping of CNC columns (Table `\ref{tab:sefc_mapping_cnc}`{=latex})

```{=latex}
\resizebox{\textwidth}{!}{%
        \begin{tabular}{lllll}
            \toprule
            \textbf{Raw Signal Name}              & \textbf{S-E-F-C Name}          & \textbf{Role}
                                                  & \textbf{Unit}                  & \textbf{Axis}                      \\
            \midrule
            \texttt{X1\_CommandPosition}          & \texttt{setpoint\_pos\_0}      & Setpoint      & mm       & X       \\
            \texttt{X1\_CommandVelocity}          & \texttt{setpoint\_vel\_0}      & Setpoint      & mm/s     & X       \\
            \texttt{X1\_CommandAcceleration}      & \texttt{setpoint\_acc\_0}      & Setpoint      & mm/s$^2$ & X       \\
            \texttt{X1\_ActualPosition}           & \texttt{feedback\_pos\_0}      & Feedback      & mm       & X       \\
            \texttt{X1\_ActualVelocity}           & \texttt{feedback\_vel\_0}      & Feedback      & mm/s     & X       \\
            \texttt{X1\_ActualAcceleration}       & \texttt{feedback\_acc\_0}      & Feedback      & mm/s$^2$ & X       \\
            \texttt{X1\_CurrentFeedback}          & \texttt{feedback\_current\_0}  & Feedback      & A        & X       \\
            \texttt{X1\_OutputCurrent}            & \texttt{effort\_current\_0}    & Effort        & A        & X       \\
            \texttt{X1\_OutputVoltage}            & \texttt{effort\_voltage\_0}    & Effort        & V        & X       \\
            \texttt{X1\_OutputPower}              & \texttt{effort\_power\_0}      & Effort        & W        & X       \\
            \texttt{X1\_DCBusVoltage}             & \texttt{ctx\_busvoltage\_0}    & Context       & V        & X       \\
            \textit{(Pattern repeats for Y1 $\to$ axis 1, Z1 $\to$ axis 2)}                         \\
            \midrule
            \texttt{S1\_CommandPosition}          & \texttt{setpoint\_pos\_3}      & Setpoint      & deg      & Spindle \\
            \texttt{S1\_CommandVelocity}          & \texttt{setpoint\_vel\_3}      & Setpoint      & rpm      & Spindle \\
            \texttt{S1\_CommandAcceleration}      & \texttt{setpoint\_acc\_3}      & Setpoint      & rpm/s    & Spindle \\
            \texttt{S1\_ActualPosition}           & \texttt{feedback\_pos\_3}      & Feedback      & deg      & Spindle \\
            \texttt{S1\_ActualVelocity}           & \texttt{feedback\_vel\_3}      & Feedback      & rpm      & Spindle \\
            \texttt{S1\_ActualAcceleration}       & \texttt{feedback\_acc\_3}      & Feedback      & rpm/s    & Spindle \\
            \texttt{S1\_CurrentFeedback}          & \texttt{feedback\_current\_3}  & Feedback      & A        & Spindle \\
            \texttt{S1\_OutputCurrent}            & \texttt{effort\_current\_3}    & Effort        & A        & Spindle \\
            \texttt{S1\_OutputVoltage}            & \texttt{effort\_voltage\_3}    & Effort        & V        & Spindle \\
            \texttt{S1\_OutputPower}              & \texttt{effort\_power\_3}      & Effort        & W        & Spindle \\
            \texttt{S1\_DCBusVoltage}             & \texttt{ctx\_busvoltage\_3}    & Context       & V        & Spindle \\
            \texttt{S1\_SystemInertia}            & \texttt{ctx\_inertia\_3}       & Context       & ---      & Spindle \\
            \midrule
            \texttt{M1\_CURRENT\_PROGRAM\_NUMBER} & \texttt{ctx\_program\_number}  & Context       & ---      & ---     \\
            \texttt{M1\_sequence\_number}         & \texttt{ctx\_sequence\_number} & Context       & ---      & ---     \\
            \texttt{M1\_CURRENT\_FEEDRATE}        & \texttt{ctx\_feedrate}         & Context       & mm/min   & ---     \\
            \texttt{Machining\_Process}           & \texttt{ctx\_process\_phase}   & Context       & enum     & ---     \\
            \bottomrule
        \end{tabular}%
    }
```
## B.4`\quad `{=latex}AURSAD Source (UR3e Screwdriving) {#b.4aursad-source-ur3e-screwdriving .unnumbered}

Per-joint signals follow a fixed pattern for joints $i \in \{0,\ldots,5\}$; one representative joint (joint 0) is shown below. (Table `\ref{tab:sefc_mapping_aursad}`{=latex})

```{=latex}
\resizebox{\textwidth}{!}{%
        \begin{tabular}{lllll}
            \toprule
            \textbf{Raw Signal Name}                    & \textbf{S-E-F-C Name}                     & \textbf{Role}
                                                        & \textbf{Unit}                             & \textbf{Notes}                                                  \\
            \midrule
            \texttt{target\_q\_0}                       & \texttt{setpoint\_pos\_0}                 & Setpoint       & rad           & Joint 0                        \\
            \texttt{target\_qd\_0}                      & \texttt{setpoint\_vel\_0}                 & Setpoint       & rad/s         &                                \\
            \texttt{target\_qdd\_0}                     & \texttt{setpoint\_acc\_0}                 & Setpoint       & rad/s$^2$     &                                \\
            \texttt{target\_current\_0}                 & \texttt{setpoint\_current\_0}             & Setpoint       & A             &                                \\
            \texttt{target\_moment\_0}                  & \texttt{setpoint\_torque\_0}              & Setpoint       & Nm            &                                \\
            \texttt{actual\_q\_0}                       & \texttt{feedback\_pos\_0}                 & Feedback       & rad           &                                \\
            \texttt{actual\_qd\_0}                      & \texttt{feedback\_vel\_0}                 & Feedback       & rad/s         &                                \\
            \texttt{actual\_current\_0}                 & \texttt{effort\_current\_0}               & Effort         & A             &                                \\
            \texttt{actual\_control\_output\_0}         & \texttt{effort\_control\_0}               & Effort         & ---           &                                \\
            \texttt{actual\_joint\_voltage\_0}          & \texttt{effort\_voltage\_0}               & Effort         & V             &                                \\
            \texttt{joint\_temperatures\_0}             & \texttt{ctx\_temp\_0}                     & Context        & \textdegree C &                                \\
            \texttt{joint\_mode\_0}                     & \texttt{ctx\_joint\_mode\_0}              & Context        & enum          &                                \\
            \texttt{target\_TCP\_pose\_0}               & \texttt{setpoint\_pos\_cartesian\_0}      & Setpoint       & m/rad         &                                \\
            \texttt{target\_TCP\_speed\_0}              & \texttt{setpoint\_vel\_cartesian\_0}      & Setpoint       & m/s           &                                \\
            \texttt{actual\_TCP\_pose\_0}               & \texttt{feedback\_pos\_cartesian\_0}      & Feedback       & m/rad         &                                \\
            \texttt{actual\_TCP\_speed\_0}              & \texttt{feedback\_vel\_cartesian\_0}      & Feedback       & m/s           &                                \\
            \texttt{actual\_TCP\_force\_0}              & \texttt{effort\_force\_cartesian\_0}      & Effort         & N             &                                \\
            \texttt{actual\_tool\_accelerometer\_0/1/2} & \texttt{auxiliary\_accel\_tool\_0/1/2}
                                                        & ---                                       & m/s$^2$        & Tool IMU                                       \\
            \midrule
            \texttt{output\_double\_register\_24}       & \texttt{feedback\_torque\_tool}           & Feedback       & Nm            & Tool torque                    \\
            \texttt{output\_double\_register\_25}       & \texttt{effort\_torque\_tool}             & Effort         & Nm            &                                \\
            \texttt{output\_double\_register\_26}       & \texttt{setpoint\_torque\_tool}           & Setpoint       & Nm            &                                \\
            \texttt{output\_double\_register\_27}       & \texttt{setpoint\_torque\_gradient\_tool} & Setpoint       & Nm/s          &                                \\
            \midrule
            \texttt{actual\_main\_voltage}              & \texttt{ctx\_main\_voltage}               & Context        & V             &                                \\
            \texttt{actual\_robot\_voltage}             & \texttt{ctx\_robot\_voltage}              & Context        & V             &                                \\
            \texttt{actual\_robot\_current}             & \texttt{ctx\_robot\_current}              & Context        & A             &                                \\
            \texttt{speed\_scaling}                     & \texttt{ctx\_speed\_scaling}              & Context        & ---           &                                \\
            \texttt{target\_speed\_fraction}            & \texttt{ctx\_target\_speed\_fraction}     & Context        & ---           &                                \\
            \texttt{actual\_momentum}                   & \texttt{ctx\_momentum}                    & Context        & kg$\cdot$m/s  &                                \\
            \texttt{robot\_mode}                        & \texttt{ctx\_robot\_mode}                 & Context        & enum          &                                \\
            \texttt{safety\_mode}                       & \texttt{ctx\_safety\_mode}                & Context        & enum          &                                \\
            \texttt{runtime\_state}                     & \texttt{ctx\_runtime\_state}              & Context        & enum          &                                \\
            \texttt{label}                              & \texttt{raw\_label}                       & ---            & ---           & 0=Normal, 1=Damaged screw,     \\
                                                        &                                           &                &               & 2=Extra part, 3=Missing screw, \\
                                                        &                                           &                &               & 4=Damaged thread               \\
            \bottomrule
        \end{tabular}%
    }
```
## B.5`\quad `{=latex}voraus-AD Source (Yu-Cobot) {#b.5voraus-ad-source-yu-cobot .unnumbered}

Per-joint signals follow the same index pattern for joints $i \in \{1,\ldots,6\}$ (1-indexed in source); one representative joint is shown. (Table `\ref{tab:sefc_mapping_voraus}`{=latex})

```{=latex}
\small
```
::: {#tab:sefc_mapping_voraus}
  **Raw Signal Name**       **S-E-F-C Name**          **Role**   **Unit**    **Notes**
  ------------------------- ------------------------- ---------- ----------- -------------------
  `target_position_1`       `setpoint_pos_0`          Setpoint   rad         Joint 1$\to$idx 0
  `target_velocity_1`       `setpoint_vel_0`          Setpoint   rad/s
  `target_acceleration_1`   `setpoint_acc_0`          Setpoint   rad/s$^2$
  `target_torque_1`         `setpoint_torque_0`       Setpoint   Nm
  `joint_position_1`        `feedback_pos_0`          Feedback   rad
  `joint_velocity_1`        `feedback_vel_0`          Feedback   rad/s
  `motor_position_1`        `feedback_motor_pos_0`    Feedback   rad
  `motor_velocity_1`        `feedback_motor_vel_0`    Feedback   rad/s
  `torque_sensor_a_1`       `feedback_torque_a_0`     Feedback   Nm
  `torque_sensor_b_1`       `feedback_torque_b_0`     Feedback   Nm
  `motor_torque_1`          `effort_motor_torque_0`   Effort     Nm
  `motor_iq_1`              `effort_current_iq_0`     Effort     A
  `motor_id_1`              `effort_current_id_0`     Effort     A
  `power_motor_el_1`        `effort_power_el_0`       Effort     W
  `power_motor_mech_1`      `effort_power_mech_0`     Effort     W
  `power_load_mech_1`       `effort_power_load_0`     Effort     W
  `motor_voltage_1`         `effort_voltage_0`        Effort     V
  `computed_inertia_1`      `ctx_inertia_0`           Context    ---
  `computed_torque_1`       `ctx_computed_torque_0`   Context    Nm
  `supply_voltage_1`        `ctx_busvoltage_0`        Context    V
  `brake_voltage_1`         `ctx_brake_voltage_0`     Context    V
  `robot_voltage`           `ctx_robot_voltage`       Context    V           Global
  `robot_current`           `ctx_robot_current`       Context    A           Global
  `io_current`              `ctx_io_current`          Context    A           Global
  `system_current`          `ctx_system_current`      Context    A           Global
  `anomaly`                 `ctx_is_anomaly`          ---        bool        Label
  `category`                `ctx_anomaly_category`    ---        str         Fault type
  `setting`                 `ctx_setting`             ---        str

  : S-E-F-C mapping for the voraus-AD source (representative joint 1 pattern; repeats for joints 2--6).
:::

## B.6`\quad `{=latex}Isaac Sim UR5 (Synthetic) {#b.6isaac-sim-ur5-synthetic .unnumbered}

Mapping of Isaac Sim UR5 columns (Table  `\ref{tab:sefc_mapping_isaac}`{=latex})

```{=latex}
\resizebox{\textwidth}{!}{%
        \begin{tabular}{llll}
            \toprule
            \textbf{Signal Group (Raw Prefix)}             & \textbf{Described Fields}              & \textbf{S-E-F-C Role} & \textbf{Unit}       \\
            \midrule
            \texttt{episode}, \texttt{step}, \texttt{time} & Global/episode steps, sim/wall time    & Metadata              & count / s           \\
            \texttt{state\_machine}, \texttt{phase}        & Task, controller phases, event IDs     & Context               & enum / str          \\
            \midrule
            \texttt{joint\_cmd\_pos\_rad\_*}               & Commanded joint positions ($\times$6)  & Setpoint              & rad                 \\
            \texttt{joint\_cmd\_vel\_radps\_*}             & Commanded joint velocities ($\times$6) & Setpoint              & rad/s               \\
            \texttt{joint\_pos\_rad\_*}                    & Actual joint positions ($\times$6)     & Feedback              & rad                 \\
            \texttt{joint\_vel\_radps\_*}                  & Actual joint velocities ($\times$6)    & Feedback              & rad/s               \\
            \texttt{joint\_accel\_radps2\_*}               & Actual joint accelerations ($\times$6) & Feedback              & rad/s$^2$           \\
            \texttt{joint\_torque\_nm\_*}                  & Joint applied torques ($\times$6)      & Effort                & Nm                  \\
            \texttt{joint\_pos\_error\_rad\_*}             & Tracking error per joint ($\times$6)   & Context               & rad                 \\
            \midrule
            \texttt{ee\_cmd\_pos\_*}, \texttt{quat\_*}     & Commanded TCP pose (pos, quat)         & Setpoint              & m / ---             \\
            \texttt{ee\_pos\_*}, \texttt{quat\_*}          & Actual TCP pose (pos, quat)            & Feedback              & m / ---             \\
            \texttt{ee\_euler\_*\_rad}                     & Actual TCP orientation (RPY)           & Feedback              & rad                 \\
            \texttt{ee\_linvel\_*}, \texttt{angvel\_*}     & TCP velocities (linear, angular)       & Feedback              & m/s / rad/s         \\
            \texttt{ee\_linacc\_*}, \texttt{angacc\_*}     & TCP accelerations (linear, angular)    & Feedback              & m/s$^2$ / rad/s$^2$ \\
            \midrule
            \texttt{gripper\_cmd\_rad}                     & Commanded gripper position             & Setpoint              & rad                 \\
            \texttt{gripper\_pos\_rad}                     & Actual gripper position                & Feedback              & rad                 \\
            \texttt{gripper\_attached}                     & Gripper logical contact state          & Context               & bool                \\
            \texttt{contact\_force\_*\_n}                  & Physical EE contact force (XYZ, mag)   & Effort                & N                   \\
            \texttt{contact\_torque\_*\_nm}                & Physical EE contact torque (XYZ, mag)  & Effort                & Nm                  \\
            \midrule
            \texttt{cube\_pos\_*}, \texttt{quat\_*}        & Target object pose (pos, quat)         & Context               & m / ---             \\
            \texttt{cube\_linvel\_*}, \texttt{angvel\_*}   & Target object velocities               & Context               & m/s / rad/s         \\
            \texttt{ee\_cube\_offset\_*}                   & Relative distance to target            & Context               & m                   \\
            \midrule
            \texttt{cube\_mass\_kg}                        & Domain rand: payload mass              & Context               & kg                  \\
            \texttt{cube\_friction\_coeff}                 & Domain rand: target object friction    & Context               & ---                 \\
            \texttt{cube\_width/depth/height\_m}           & Domain rand: target dimensions         & Context               & m                   \\
            \bottomrule
        \end{tabular}%
    }
```
# Full Fault Catalog {#app:fault_catalog}

Table `\ref{tab:fault_catalog}`{=latex} lists all 27 fault types injected during laboratory data collection.

```{=latex}
\scriptsize
```
::: {#tab:fault_catalog}
  `\arraybackslash`{=latex}**Fault**                         `\arraybackslash`{=latex} **Explanation**                                                                                                                                   `\arraybackslash`{=latex} **Injection Procedure**                                                                                       **PP**        **Scr**        **PiH**
  ---------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------- -------------- -------------- --------------
  `\arraybackslash`{=latex}Damaged screw thread              `\arraybackslash`{=latex} Screw thread physically damaged, preventing proper engagement during tightening.                                                                  `\arraybackslash`{=latex} Pre-damaged the screw thread with sandpaper.                                                                 $\times$     $\checkmark$     $\times$
  `\arraybackslash`{=latex}Missing screw                     `\arraybackslash`{=latex} Tightening is attempted with no screw present.                                                                                                    `\arraybackslash`{=latex} Removed the screw from screwdriver before the cycle.                                                         $\times$     $\checkmark$     $\times$
  `\arraybackslash`{=latex}Damaged plate thread              `\arraybackslash`{=latex} The threaded hole in the plate is damaged, preventing engagement.                                                                                 `\arraybackslash`{=latex} Pre-damaged the plate hole with a metal screwdriver.                                                         $\times$     $\checkmark$     $\times$
  `\arraybackslash`{=latex}Loosening phase                   `\arraybackslash`{=latex} A counterclockwise loosening rotation replaces tightening; a normal phase with a distinct signal. Counted as an anomaly to match AURSAD schema.   `\arraybackslash`{=latex} Reversed the rotation direction in the controller program to execute a counterclockwise loosening pass.      $\times$     $\checkmark$     $\times$
  `\arraybackslash`{=latex}Gripper activation failure        `\arraybackslash`{=latex} The vacuum gripper fails to activate and never picks up the box.                                                                                  `\arraybackslash`{=latex} Disabled the gripper activation command in the robot program.                                              $\checkmark$     $\times$       $\times$
  `\arraybackslash`{=latex}Gripper release during motion     `\arraybackslash`{=latex} The gripper releases the payload mid-trajectory, causing an abrupt payload loss.                                                                  `\arraybackslash`{=latex} Triggered a programmatic gripper-release command at a scripted timestep mid-trajectory.                    $\checkmark$     $\times$       $\times$
  `\arraybackslash`{=latex}Additional axis payload           `\arraybackslash`{=latex} A dead weight attached to one link increases inertia and gravity loading on all joints.                                                           `\arraybackslash`{=latex} Bolted calibrated weights of varying mass to one robot link.                                               $\checkmark$   $\checkmark$     $\times$
  `\arraybackslash`{=latex}Collision with foam object        `\arraybackslash`{=latex} Contact with a soft foam block produces a brief TCP force spike without a protective stop.                                                        `\arraybackslash`{=latex} Placed a foam cube directly in the programmed TCP trajectory.                                              $\checkmark$   $\checkmark$   $\checkmark$
  `\arraybackslash`{=latex}Unexpected payload weight         `\arraybackslash`{=latex} The transported box has a weight that deviates from the nominal payload configuration.                                                            `\arraybackslash`{=latex} Swapped the nominal box for a known heavier or lighter one.                                                $\checkmark$     $\times$       $\times$
  `\arraybackslash`{=latex}Invalid gripping position         `\arraybackslash`{=latex} Timing error: the gripper closes after the arm has begun lifting, gripping the object off-centre.                                                 `\arraybackslash`{=latex} Added a sleep() call in the controller program so gripper closure lags the lift motion.                    $\checkmark$     $\times$       $\times$
  `\arraybackslash`{=latex}Unstable mounting platform        `\arraybackslash`{=latex} Base instability introduces low-frequency vibrations into the arm.                                                                                `\arraybackslash`{=latex} Placed 8 layers of towels under the base plate.                                                            $\checkmark$     $\times$       $\times$
  `\arraybackslash`{=latex}Joint position limit violation    `\arraybackslash`{=latex} A joint moves outside its configured soft or hard position limits, triggering a safety stop.                                                      `\arraybackslash`{=latex} Random waypoint slightly beyond the configured soft joint limit.                                           $\checkmark$     $\times$       $\times$
  `\arraybackslash`{=latex}TCP frame misconfiguration        `\arraybackslash`{=latex} TCP frame or mounting orientation misconfigured at the controller; gravity torques deviate.                                                       `\arraybackslash`{=latex} Entered an incorrect TCP offset or mounting angle in the controller settings.                              $\checkmark$   $\checkmark$   $\checkmark$
  `\arraybackslash`{=latex}Payload weight misconfiguration   `\arraybackslash`{=latex} Payload mass misconfigured while a tool or workpiece is physically attached.                                                                      `\arraybackslash`{=latex} Left configured payload weight at multiple wrong mass configurations.                                      $\checkmark$   $\checkmark$     $\times$
  `\arraybackslash`{=latex}External arm disturbance          `\arraybackslash`{=latex} A continuous external force pulls or pushes the TCP during motion.                                                                                `\arraybackslash`{=latex} Anchored an elastic rope between the bench frame and the tool flange.                                      $\checkmark$   $\checkmark$   $\checkmark$
  `\arraybackslash`{=latex}Mild payload CoG misconfig.       `\arraybackslash`{=latex} Payload CoG specified at an incorrect offset from the tool flange; gravity compensation is wrong.                                                 `\arraybackslash`{=latex} Entered a CoG offset in the payload configuration that differs from physical CoG.                          $\checkmark$   $\checkmark$   $\checkmark$
  `\arraybackslash`{=latex}Collision with hanging cable      `\arraybackslash`{=latex} A loose cable drags along a robot link or the tool flange during motion.                                                                          `\arraybackslash`{=latex} Suspended a loose cable across the trajectory at arm height.                                               $\checkmark$   $\checkmark$   $\checkmark$
  `\arraybackslash`{=latex}Collision with cardboard          `\arraybackslash`{=latex} A cardboard carton in the trajectory provides moderate resistance; may trigger a protective stop.                                                 `\arraybackslash`{=latex} Placed a free-standing or braced cardboard box in the programmed trajectory.                               $\checkmark$   $\checkmark$   $\checkmark$
  `\arraybackslash`{=latex}Collision with rigid object       `\arraybackslash`{=latex} A rigid plastic block in the TCP path triggers an immediate protective stop.                                                                      `\arraybackslash`{=latex} Clamped a rigid plastic block in the programmed TCP path.                                                  $\checkmark$   $\checkmark$   $\checkmark$
  `\arraybackslash`{=latex}Peg insertion misalignment        `\arraybackslash`{=latex} Peg approaches the hole at an angular or lateral offset and jams against the rim.                                                                 `\arraybackslash`{=latex} Added a recorded lateral offset at the insertion approach waypoint.                                          $\times$       $\times$     $\checkmark$
  `\arraybackslash`{=latex}Hole obstruction                  `\arraybackslash`{=latex} Foreign object or debris in the hole prevents full insertion.                                                                                     `\arraybackslash`{=latex} Placed a small object (metal screw) inside the hole before insertion.                                        $\times$       $\times$     $\checkmark$
  `\arraybackslash`{=latex}Incorrect insertion depth         `\arraybackslash`{=latex} Insertion terminates at an incorrect Z depth due to a misconfigured waypoint.                                                                     `\arraybackslash`{=latex} Shifted the insertion endpoint waypoint Z by recorded offset from nominal.                                   $\times$       $\times$     $\checkmark$
  `\arraybackslash`{=latex}Peg surface contamination         `\arraybackslash`{=latex} Contamination or roughness on the peg raises insertion friction and produces stick-slip.                                                          `\arraybackslash`{=latex} Applied dry chalk powder to the peg surface.                                                                 $\times$       $\times$     $\checkmark$
  `\arraybackslash`{=latex}Fixture displacement              `\arraybackslash`{=latex} Insertion fixture shifted laterally, breaking the match between programmed approach and actual hole.                                              `\arraybackslash`{=latex} Physically shifted the hole fixture by recorded offset without updating program.                             $\times$       $\times$     $\checkmark$
  `\arraybackslash`{=latex}Self-collision                    `\arraybackslash`{=latex} Arm configuration causes a link to contact the robot body or mounting fixture.                                                                    `\arraybackslash`{=latex} Random waypoint that forces a self-colliding configuration.                                                $\checkmark$     $\times$       $\times$
  `\arraybackslash`{=latex}Missing box                       `\arraybackslash`{=latex} Box absent from the pick position; the gripper closes on empty air.                                                                               `\arraybackslash`{=latex} Removed the box from the pick position before the episode started.                                         $\checkmark$     $\times$       $\times$
  `\arraybackslash`{=latex}Missing peg                       `\arraybackslash`{=latex} Arm descends into the hole empty-handed; insertion produces no contact force.                                                                     `\arraybackslash`{=latex} Removed the peg from the gripper before the episode started.                                                 $\times$       $\times$     $\checkmark$

  : Complete Fault Catalog. Checkmarks ($\checkmark$) indicate whether the fault is included in the Pick-and-Place (PP), Screwing (Scr), and Peg-in-Hole (PiH) task recordings. Crosses ($\times$) indicate absence.
:::

# Multi-Step Forecasting Metrics {#app:forecasting}

::: {#tab:forecasting_metrics}
                                                                               **H = 50**                  **H = 100**                  **H = 200**
  ------------------------------------------------------------------- ---------------------------- ---------------------------- ---------------------------- ---------------------------- ---------------------------- ----------------------------
  2-3`\cmidrule`{=latex}(lr)4-5`\cmidrule`{=latex}(lr)6-7 **Model**             **MSE**                      **MAE**                      **MSE**                      **MAE**                      **MSE**                      **MAE**
  Linear                                                                   $28.17_{\pm 0.28}$           $3.25_{\pm 0.02}$           $541.22_{\pm 36.57}$          $12.99_{\pm 0.27}$         $6930.06_{\pm 67.51}$          $51.31_{\pm 0.84}$
  Flat MLP                                                                 $1.69_{\pm 0.05}$            $0.80_{\pm 0.02}$           $67.02_{\pm 17.12}$           $4.15_{\pm 0.46}$          $1939.57_{\pm 160.39}$         $24.43_{\pm 1.33}$
  TCN                                                                      $0.46_{\pm 0.03}$            $0.46_{\pm 0.02}$           $102.63_{\pm 30.85}$          $4.68_{\pm 0.78}$          $2940.49_{\pm 218.03}$         $30.20_{\pm 1.73}$
  **TCN-Transformer**                                                  $\mathbf{0.00_{\pm 0.00}}$   $\mathbf{0.01_{\pm 0.00}}$   $\mathbf{0.00_{\pm 0.00}}$   $\mathbf{0.03_{\pm 0.00}}$   $\mathbf{0.11_{\pm 0.01}}$   $\mathbf{0.18_{\pm 0.01}}$

  : Multi-step forecasting on voraus-AD (Yu-Cobot) Pick & Place, held-out normal episodes. MSE ($\times 10^{-4}$ rad$^2$) and MAE ($\times 10^{-2}$ rad) $\pm$ std over test episodes. Lower is better. Values below $0.005$ in the chosen unit are rounded to $0.00$.
:::
