Paper · 2025-09-21 · cs.RO
FILIC: Dual-Loop Force-Guided Imitation Learning with Impedance Torque Control for Contact-Rich Manipulation Tasks
FILIC pairs a Transformer imitation policy (RGB plus estimated end-effector force, 25 Hz) with a joint-space impedance torque loop (2 kHz). The force comes from joint torques through a Jacobian pseudo-inverse and a MuJoCo digital twin, with no force/torque sensor. Author-reported: simulated peg insertion 68.0% to 90.0%; real tasks 26.6-46.7% (position only) vs 76.6-83.3% (estimated force).
Imitation learningImpedance controlAction chunkingDigital twinimitation-learningforce-estimationimpedance-controlcontact-rich-manipulationsensorless-force-sensing
arXivPDFCodeMarkdown11 min read
AI-compiled by claude-haiku-5-5 on 2026-11-01, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.
In plain words
Robot arms that press, insert or twist mostly work from where their hand is. They do not feel how hard they push. A wrist force sensor fixes that, but it costs money and needs extra hardware. FILIC avoids the sensor. It estimates the push at the hand from the torques in the arm's joints, and it uses a physics model of the arm to subtract the torque the joints need just to hold their pose.
The arm then has two layers of control. The top layer is a learned policy, trained from human demonstrations. It looks at camera images, the hand position and the estimated push, and proposes where the hand should go next. The bottom layer is a spring-and-damper controller. It turns that target into joint torques, so the arm gives way when it touches something instead of pushing through it.
This matters for tasks such as inserting a plug, pressing a button, or tightening a cap. A policy that only sees positions can fail to recover from a misaligned part or fail to finish tightening. The demonstrations are also recorded with a handheld controller that vibrates faster as the force grows, so the operator can feel the contact and the data carries the force cues the policy learns from.
TL;DR
FILIC is a two-loop controller for contact-rich manipulation. A policy that follows the ACT architecture reads two camera streams, the end-effector pose and an estimated 6-D end-effector wrench, and outputs target poses at 25 Hz. A joint-space impedance law running at 2 kHz turns each target into torque commands. The wrench comes from joint torques through a Jacobian pseudo-inverse, with a MuJoCo digital twin for the expected torques, so no force/torque sensor is needed. The released code contains only the wrench estimator, not the policy or the controller.
Problem
Imitation-learning policies that output joint positions or 6-DOF poses can create large internal forces during contact, which risks damage to the robot and to the environment §1. An end-effector force signal would give richer contact feedback, but wrist force/torque sensors are costly and scarce §1. Prior work often uses force only as an auxiliary input to position control rather than for compliant execution §1. The target setting is low-cost, sensorless arms that run stable, compliant torque-level control §1.
The estimator assumes the arm model matches the real arm well enough for the dynamics terms to cancel §4.2. The controller assumes the tasks are approximately quasi-static, so the inertia term is dropped and only spring and damper terms remain §4.1. Both assumptions are stated; neither is tested beyond the experiments in §5.
Method
The system has three parts: an outer-loop policy, an inner-loop impedance controller, and a wrench estimator. A handheld teleoperation device with vibrotactile feedback collects the demonstrations §4.3. The figures are fig. 1 (overview), fig. 2 (detailed architecture) and fig. 3 (demonstration force traces).
Outer loop: policy at 25 Hz §4.1 fig. 2
- Two external RGB cameras are down-sampled to 25 Hz. Each stream goes through a ResNet backbone. The paper does not name the ResNet variant §4.1.
- The 6-D estimated wrench goes through an MLP. The visual features and the force features are fused by a cross-attention module §4.1 fig. 2.
- The fused features are concatenated with the end-effector pose features
(also through an MLP) and with a CVAE style latent
Z. During trainingZis computed from the action pose sequence and the current pose. At inference it is omitted §4.1. - A Transformer outputs a sequence of 6-DOF end-effector target poses at 25 Hz. It uses action chunking with temporal ensembling. Apart from the perception input module, the architecture follows ACT §4.1.
Inner loop: impedance torque control at 2 kHz §4.1 eq. 5
- Each control cycle, the policy's target pose is converted to joint targets
q_hatby real-time inverse kinematics. The IK method is not stated §4.1. - Joint positions and velocities are read at 250 Hz. The gravity and Coriolis
feedforward
tau_hatis refreshed at 250 Hz §4.1. - The torque command is computed at 2 kHz with eq. 5. The target velocity
v_hatis set to 0. The gainsKandBare fixed presets whose values are not stated §4.1. Variable impedance is left to future work §6. - The paper maps eq. 5 onto the actuator's MIT control mode, which takes a target position, a target velocity and a feedforward torque, with position and velocity gains §3.3 eq. 4 §4.1.
External force estimation with a digital twin §4.2 eq. 6
- The measured joint positions, velocities and torques are copied into a MuJoCo model of the arm in real time §4.2.
- The expected joint torque
tau_invis the twin's inverse-dynamics torque at the current state §4.2. - The external wrench is
F_ext = J(q)^(T+) (tau_obs - tau_inv), with the pseudo-inverse computed by SVD eq. 6 §4.2. - The output is
[fx, fy, fz, tx, ty, tz]at the end effector §4.1.
Demonstration collection §4.3
- The estimated end-effector force is mapped to vibration cues. The vibration frequency increases in discrete steps as the force grows. The thresholds and the device are not stated §4.3.
Equations used by the method:
Joint-space dynamics with external torque, eq. 1:
M(q)\ddot{q} + C(q,\dot{q})\dot{q} + g(q) = \tau + \tau_{ext}
Mapping from the end-effector wrench to joint torques, eq. 2:
\tau_{ext} = J(q)^T F_{ext}
Joint-space impedance law used by the controller, eq. 5:
\tau_{cmd} = B(\hat{v} - v) + K(\hat{q} - q) + \hat{\tau}
Wrench estimator, eq. 6:
F_{ext} = J(q)^{T+}(\tau_{obs} - \tau_{inv})
# External end-effector wrench from joint torques [eq. 6] [§4.2]
# Input: q, dq (n,), tau_obs (n,) measured joint torques
# Output: wrench (6,) = [fx, fy, fz, tx, ty, tz] at the end effector
def estimate_wrench(q, dq, tau_obs, twin):
# 1. Torque the twin needs to hold this pose (zero acceleration) [§4.2]
tau_inv = inverse_dynamics(twin, q, dq, qacc=0) # (n,)
# 2. End-effector Jacobian, translational rows above rotational [§4.2]
jacobian = stack_rows(jac_position(twin, q),
jac_rotation(twin, q)) # (6, n)
# 3. Least-squares inversion of J^T via SVD [eq. 6]
residual = tau_obs - tau_inv # (n,)
wrench = pinv(transpose(jacobian)) @ residual # (6,)
return wrench# Joint-space impedance torque command [eq. 5] [§4.1]
# Inputs: q_hat (n,) IK target at 25 Hz, q and v at 250 Hz, tau_hat (n,)
# Output: torque command (n,) computed at 2 kHz
def impedance_torque(q_hat, q, v, tau_hat, stiffness, damping):
# 1. Velocity target is zero in the paper [§4.1]
v_hat = zeros_like(q) # (n,)
# 2. Spring and damper pull toward the target, plus feedforward [eq. 5]
tau_cmd = (damping * (v_hat - v)
+ stiffness * (q_hat - q)
+ tau_hat) # (n,)
return tau_cmdHyperparameters
| Name | Value | Where | Notes |
|---|---|---|---|
| learning rate | 2e-5 | tab. 1 | optimizer, schedule and warmup not stated |
| batch size | 16 | tab. 1 | |
| encoder layers | 4 | tab. 1 | |
| decoder layers | 7 | tab. 1 | |
| feedforward dimension | 3200 | tab. 1 | |
| hidden dimension | 512 | tab. 1 | |
| attention heads | 8 | tab. 1 | |
| chunk size | 25 | tab. 1 §4.1 | 25 steps, which is 1 s at 25 Hz (derived) |
| beta | 10 | tab. 1 | not defined in the text |
| dropout | 0.1 | tab. 1 | |
| training steps or epochs | not stated | ||
| ResNet variant, image resolution | not stated | §4.1 | |
| temporal ensemble weighting | not stated | §4.1 | |
| CVAE latent size, encoder layout | not stated | §4.1 | |
| policy and camera rate | 25 Hz | §4.1 fig. 2 | |
| joint state and gravity/Coriolis feedforward rate | 250 Hz | §4.1 | |
| impedance loop rate | 2 kHz | §4.1 fig. 1 | |
target velocity v_hat | 0 | §4.1 eq. 5 | |
stiffness K, damping B | preset, values not stated | §4.1 eq. 5 | |
| IK method | not stated | §4.1 | |
| sim peg / hole | 0.95 cm square peg, 1 cm square hole | §5.3.1 | the 0.05 cm slack is derived |
| sim hole offset | random 1 mm per episode | §5.3.1 | |
| sim demonstrations | 150 (50 single-shot, 100 with corrections) | §5.3.1 | |
| sim evaluation trials | 50 per condition | §5.4 | |
| real demonstrations | 30 per task (adapter: 10 single-shot, 20 corrective) | §5.3.2 | only successful runs kept |
| real evaluation trials | 30 per condition | §5.4 | |
| static load test | 30 repeated estimates per load, 6-DOF AIRBOT Play | §5.1 | loads and results are in fig. 4 only |
| gravitational acceleration used for loads | 9.81 m/s² | fig. 4 | |
| haptic feedback | vibration frequency rises in discrete steps with force | §4.3 | thresholds not stated |
Results
Author-reported. The policy experiments compare three inputs with the same architecture and training setup: end-effector position only, position plus joint torque, and position plus estimated end-effector force §5.4. All variants use the RGB images and the end-effector position §5.4. Simulation: MuJoCo peg-in-hole, a 6-DOF manipulator, two RGB cameras, 50 trials per condition §5.3.1 §5.4. Real world: four tasks on a robot arm that the paper does not name, 30 trials per condition §5.3.2 §5.4.
Simulation success rate tab. 2:
| Policy input | Success (%) |
|---|---|
| EE position | 68.0 |
| EE position + joint torque | 80.0 |
| EE position + EE force | 90.0 |
Real-robot success rate across four tasks tab. 3:
| Task | Pos | Pos + JT | Pos + EF |
|---|---|---|---|
| Plug adapter into socket | 46.7 | 63.3 | 80.0 |
| Operate emergency stop button | 43.3 | 60.0 | 83.3 |
| Fix C-clamp to table | 30.0 | 63.3 | 76.6 |
| Tighten bottle cap | 26.6 | 70.0 | 80.0 |
Pos = EE position; JT = joint torque; EF = estimated EE force tab. 3.
The static load test §5.1 reports the mean and standard deviation of the Z-axis force error for each load, over 30 repeated estimates fig. 4. The numerical values are not given in the text, so this card reports no error figures. The traces in §5.2 and fig. 3 show contact events as local extrema in the force or torque signal. They are qualitative only.
The gains from estimated force over position only are +22.0 points in simulation and +33.3, +40.0, +46.6 and +53.4 points on the four real tasks §5.4. The gains from estimated force over joint torque are +10.0 points in simulation and +16.7, +23.3, +13.3 and +10.0 points on the real tasks §5.4.
Paper vs code
The official repository is OpenGHz/mujoco-wrench-estimator (MIT, copyright
the first author) LICENSE. The paper links it in the abstract
[abstract]. It contains only the wrench estimator and a simulation example
README.md. It has no policy, training code, impedance controller,
teleoperation or haptic code, and no arm model for the real robot.
- Scope. The paper describes the whole system §4. The code covers only eq. 6. Everything else must be built from the paper text.
- Estimator equation. Paper:
pinv(J^T)(tau_obs - tau_inv)eq. 6. Code:pinv(J.T) @ (tau_measured - tau_model), withtau_modelfrom inverse dynamics at zero acceleration wrench_estimator.py andpinvon line 66 wrench_estimator.py. The two match. - Reference point and frame. The paper does not state the point or the frame of the wrench. The code takes the Jacobian at the origin of the end-effector body, in world coordinates [code: wrench_estimator/wrench_estimator.py#L54-L61] and says so in the README README.md. The tool tip is not used.
- Digital twin. The paper says the twin is synchronized in real time and accounts for sensor noise, joint friction and mechanical compliance §4.2. The code does not model any of these. It only calls inverse dynamics on the state it is given wrench_estimator.py. Friction must be in the model file, and the example arm has no damping or friction attributes estimate_in_simulation.py. The README says friction limits the accuracy README.md.
- Torque input. The paper computes the force from joint current-derived torques §3.2. The code takes joint torque; the README says to convert current to torque first, using a per-joint constant that is not given README.md.
- Filtering. The paper does not describe filtering. The README suggests averaging over a short window README.md. The released code does no averaging.
- Singularities. The paper calls the pseudo-inverse a stable least-squares
approximation §4.2. The code calls
np.linalg.pinvwith no damping or cutoff set wrench_estimator.py. The README warns to keep away from singularities README.md. - Validation. The example builds the torques from the same model and checks that the wrench is recovered to 1e-6 estimate_in_simulation.py. This shows the algebra is right; it does not test model mismatch on hardware.
- Impedance constants. The paper writes the MIT-mode law with
K_pandK_deq. 4 and the controller law withKandBeq. 5. It does not say whetherK = K_pandB = K_d. No code for the controller is released. - Estimator inputs. The paper's real-hardware pipeline is not in the repo. The MuJoCo model of the AIRBOT Play, used for the static test §5.1, is not in the repo either.
No code for the policy, the controller or the data collection is released, so their details can be checked only against the paper.
Pitfalls
- Policy and controller are not released. Optimizer, schedule, training length, ResNet variant, ensemble weighting, IK method and the impedance gains are all missing tab. 1 §4.1. Write them as "not stated" in any reimplementation and mark each choice you make.
- Two different rates for one loop. The joint state arrives at 250 Hz, but the torque law runs at 2 kHz §4.1. The paper does not say how the 250 Hz values are held or interpolated between updates. The gravity and Coriolis feedforward is also refreshed only at 250 Hz §4.1.
- The impedance law has no inertia term. The arm is treated as quasi-static §4.1. Fast motions or heavy payloads may violate this, and the paper gives no test of it.
- The estimator needs an accurate arm model. Mass, inertia and friction errors appear directly in the estimate. The paper's real-world accuracy test uses only static loads and reports them only in fig. 4 §5.1.
- Singularities are not handled. A 6-DOF arm with a 6-D wrench is inverted exactly away from singularities, with no regularization §4.2 [code: wrench_estimator/wrench_estimator.py#L66]. Near a singularity the estimate can grow, and the paper's "stable" claim is not backed by a damping term.
- Sign and frame conventions. The static test compares the estimated Z-axis force with a "downward" gravity load §5.1, but the paper does not give the sign convention for the force. Check the sign on a known load before using the output for control.
- The abstract's baseline name. The abstract calls the baseline "vision-only" [abstract]. In the experiments it is end-effector position plus RGB images §5.4. The two names describe the same baseline, but the baseline does get the hand position.
- Small trial counts, one run per cell. Simulation uses 50 trials and the real tasks 30 trials per condition §5.4. The paper reports no repeated training runs, no variance and no statistical test. The word "significantly" in the abstract is not backed by a test.
- Unnamed hardware for the policy. The robot used for the real policy experiments is not named §5.3.2. Only the static test names the AIRBOT Play §5.1.
- Demonstrations contain the corrections. The simulation data include 100 of 150 trajectories with force-guided corrections, and the real data include 20 of 30 for the adapter task §5.3. Most of the data therefore covers recovery behaviour. Results with pure single-shot demonstrations are not reported.
- Failure modes named by the authors. The position-only baseline cannot recover from lateral misalignment, and it cannot finish tightening from a loose start §5.4. The E-stop policy's final press is described as close to random §5.4. These are qualitative descriptions, not measured error rates.
- Feedback thresholds. The vibration steps and the force levels that trigger them are not stated §4.3. A reimplementation cannot match the operator feel without them.
- Geometric margin. A 1 mm random hole offset is larger than the 0.5 mm total slack implied by a 0.95 cm peg in a 1 cm hole (derived from §5.3.1), so the policy must correct laterally in every episode.
Lineage
- Builds on: ACT, Zhao et al. 2023, arXiv:2304.13705 (no card yet). The policy follows its architecture apart from the perception module §4.1. Action chunking and the CVAE latent come from it, with the latent dropped at inference §4.1.
- Builds on: the conditional VAE of Sohn et al. for the style latent §4.1.
- Compared against: only the paper's own ablations, with end-effector position only and with position plus joint torque §5.4. The introduction names other force-aware imitation methods §1 but the paper does not compare against them.
- Superseded by: not known from content already in this wiki.
Source and license
Adapted from “FILIC: Dual-Loop Force-Guided Imitation Learning with Impedance Torque Control for Contact-Rich Manipulation Tasks” by Haizhou Ge, Yufei Jia, Zheng Li, Yue Li, Zhixing Chen, Lu Shi, Lei Han, Ruqi Huang, Guyue Zhou (arXiv:2509.17053), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/OpenGHz/mujoco-wrench-estimator at commit 6e7c0ab8863e (MIT). Any quoted code is shown under that license.