A component can remain registered in an IComponentContainer after a robot places it in the world. In this case, the part stops moving with the robot, but no container-leaving transition occurs. Enable releaseToWorld in the robot’s ActionSignals properties so the release operation removes the part from the gripper container and triggers the leaving event.
Recognize the container-state mismatch
The observed sequence separates physical placement from container membership:
| Observation | Meaning |
|---|---|
| The part is grasped |
ComponentArriving is raised and the attach handler runs. |
| The release action signal changes to zero | The part is placed and remains where the robot leaves it. |
| The part remains listed in the gripper’s container | No leaving transition has occurred, so ComponentLeaving cannot run. |
Python OnTransition runs only during grasping |
The missing release transition affects both the C# and Python implementations. |
Understand why the detach handler does not run
ComponentLeaving represents a transition out of the component container. A visual release is not sufficient: the component must also be removed from the container’s membership. With releaseToWorld unset, setting the action signal to zero places the component but does not remove it from the robot or gripper container. Consequently, neither the C# ComponentLeaving handler nor the Python OnTransition callback receives a leaving transition.
Follow the container state before changing code
- Grasp a component and confirm that the attach callback runs.
- Release the component with the configured robot action signal.
- Check whether the component still appears in the gripper’s
IComponentContainer. - If it remains listed, treat the problem as release configuration rather than event subscription failure.
- If it leaves the container but the callback still does not run, then inspect the selected container behavior and event subscription path.
Enable releaseToWorld
- Open the robot action configuration.
- Locate the robot’s
ActionSignalsproperties for the grasp-and-release action. - Enable
releaseToWorld. - Retain the action signal transition used to place the component.
- Repeat the grasp-and-release cycle and inspect the component container.
The action signal and releaseToWorld perform distinct functions in the reported configuration: the zero signal places the component, while releaseToWorld makes it leave the component container.
Keep event subscription diagnostics separate
Repeatedly executing the unsubscribe statements does not correct a missing container transition. Use one unsubscribe-before-subscribe operation when initialization can run more than once, but first verify that the code references the same IComponentContainer instance and the same handler:
componentContainer.ComponentArriving -= ChangeCollisionDetectorAttach;
componentContainer.ComponentLeaving -= ChangeCollisionDetectorDetach;
componentContainer.ComponentArriving += ChangeCollisionDetectorAttach;
componentContainer.ComponentLeaving += ChangeCollisionDetectorDetach;
The evidence reports that ComponentArriving was called twice, but it does not establish the cause. Check whether initialization visits the same container more than once or executes more than once; do not attribute that duplicate call to the release configuration without confirming it.
Verify the correction
- Before grasping, record whether the part belongs to the gripper container.
- Grasp it and verify that
ChangeCollisionDetectorAttachruns. - Release it and confirm that it no longer appears in the container.
- Verify that
ChangeCollisionDetectorDetachnow runs once for the leaving transition. - Confirm that the collision detector’s node lists reflect the released state.
A detector reconfiguration call was proposed during diagnosis, but the evidence does not show that it resolved the event problem. Verify the container transition first; detector refresh logic cannot create a missing leaving event.
FAQ
Why does IComponentContainer ComponentLeaving not fire?
The component has not actually left the container. Enable releaseToWorld in the robot’s ActionSignals properties, then verify that the released part disappears from the gripper container.
Why does the released part stop moving but remain in GraspContainer?
Setting the action signal to zero can place the part without removing its container membership. The reported correction is to enable releaseToWorld.
Why does Python OnTransition run when grasping but not releasing?
OnTransition cannot report a transfer out when the part remains in the container. Correct the robot release configuration with releaseToWorld before changing the callback code.