Did you know you could subscribe to Insertion Events?

For the past few weeks, I’ve been building a debug dataset around the cable insertion challenge so I could stop guessing and start measuring what the policy was actually doing.

That meant logging everything I could reasonably get my hands on:

  • task context

  • board/module mapping

  • TF snapshots

  • initial and hover camera frames

  • plug-tip vs target distance

  • max insertion force

  • and quietly sitting there in the JSON the whole time, /scoring/insertion_event

For about three weeks, that field looked like this:

“last_insertion_event”: null

Cold. Silent. Unmoved.

A tiny JSON gravestone.

Meanwhile, the policy was getting closer and closer:

  • partial insertions

  • cleaner hover alignment

  • better plug-tip distance

  • nicer force profiles

  • promising near-misses

But still:

“last_insertion_event”: null

Then today, after reworking the flow into a much more controlled sequence

  1. hover above target

  2. verify the camera view

  3. treat fine CV as advisory instead of authoritarian

  4. feather the descent instead of full-sending it into the port, the field finally changed.

And when it changed, it was glorious:

“scoring_runtime”: {

"last_insertion_event": "/nic_card_mount_0/sfp_port_0",

"insertion_events": \[

  {

    "timestamp": "2026-03-18T12:21:30.363476",

    "message": "/nic_card_mount_0/sfp_port_0"

  }

\],

"max_force_magnitude_n": 21.487986435741192,

"max_force_vector_n": {

  "fx": 0.0967885128157264,

  "fy": -7.361223994360796,

  "fz": 20.187535123219753

}

},

That tiny line ended up being one of the most satisfying debug signals in the whole project.

A few things I learned from instrumenting the run this way:

1. Partial insertion and insertion events are not the same thing.
The scorer can award partial insertion after the fact without the runtime insertion event ever firing. That was a huge distinction.

2. Plug-tip distance matters a lot more than TCP distance.
Once I started logging plug-tip-to-target distance, the geometry of the near-misses started making sense.

3. A “good enough” hover view beats a strict CV gate.
Overly restrictive vision checks were blocking runs that were already well aligned from TF and hover positioning. The better balance was: use CV to confirm the scene, then descend carefully.

4. Feathered descent was worth the extra time.
It slowed the run down a bit, but dramatically improved consistency and eventually produced a full insertion success.

Today’s baseline score jumped to 216, with:

  • 3/3 successful trials

  • 1 true cable insertion success

  • 2 partial insertions

So yes, you can subscribe to insertion events.

And yes, seeing that field finally stop being null after weeks of staring at it felt absurdly good.

code examples of event listeners.

from geometry_msgs.msg import Point, Pose, Quaternion, Transform, WrenchStamped

#insertion event comes from parent_node

def _init_(self, parent_node):

    super().\__init_\_(parent_node)

    self.\_insertion_event_sub = self.\_parent_node.create_subscription(

        String,

        "/scoring/insertion_event",

        self.\_on_insertion_event,

        10,

    )



    self.\_wrench_sub = self.\_parent_node.create_subscription(

        WrenchStamped,

        "/fts_broadcaster/wrench",

        self.\_on_wrench,

        50,

    )

def \_on_insertion_event(self, msg: String) -> None:

    self.\_last_insertion_event = msg.data

    self.\_insertion_events.append(

        {

            "timestamp": datetime.now().isoformat(),

            "message": msg.data,

        }

    )

    self.get_logger().info(f"\[IC04-UT2\] insertion_event: {msg.data}")

def \_on_wrench(self, msg: WrenchStamped) -> None:

    fx = float(msg.wrench.force.x)

    fy = float(msg.wrench.force.y)

    fz = float(msg.wrench.force.z)

    force_mag = math.sqrt(fx \* fx + fy \* fy + fz \* fz)

    if force_mag > self.\_max_force_mag:

        self.\_max_force_mag = force_mag

        self.\_max_force_vector = {

            "fx": fx,

            "fy": fy,

            "fz": fz,

        }
2 Likes

Thank you so much for sharing!!!
I’ll definately try this out!

1 Like

No problem! Thanks!!

1 Like

OMG This post magically solved all my problems:

1 Like

Huge thanks for sharing this discovery, @No_Quarter_Robotics

1 Like

Hi, thanks for sharing this!

We’re currently seeing a similar issue: our policy can get near the port and even enter what we call a guarded-insert phase, but we still get no true insertion events. We recently diagnosed that our current “guarded” insertion is actually much coarser than our successful scripted traces, and we also don’t yet have a strong explicit hover/verify gate.

If you’re willing to share, I’d really appreciate a few practical details:

Roughly how high above the port did you stage before starting the final descent? Did you use a fixed pre-insert offset, or vary it by connector/task?

  • What signals actually determined “good enough to start insertion”?

  • Did you rely mostly on plug-tip-to-port geometry, CV confidence, dwell/stability, or some combination?

  • Was there any approximate lateral/yaw tolerance you found necessary before proceeding

  • for your feathered descent, roughly what descent step size or update scale did you use during the final insertion?

  • What force signal or threshold most often told you to stop / reseat / back out? Did you use total force magnitude only, or also lateral vs axial force? Did you find a “safe pre-insert force” threshold before starting final descent?

  • When insertion didn’t happen, what was your most effective immediate recovery

  • In your experience, what most often distinguished runs that got partial insertion only from runs that actually fired insertion_event?

any implementation-level guidance would be hugely appreciated. Thanks!

I’m just seeing this now due to recent activity and want to double check. Are we actually allowed to use the insertion event at eval time? I thought not (just like not ground truth).

For hovering, I am directly over the port hole, then I used a stepping feather insert and actually push a bit past the target. This was mainly used with ground_truth = true so I could fully confirm insertion with my dataset. Thanks! and good luck!

I am not 100% sure. This was mainly used with ground_truth = true so I could fully confirm insertion with my dataset. Thanks and good luck!