Add contact (bumper) sensor with Bool and WrenchStamped publishers - #213
Add contact (bumper) sensor with Bool and WrenchStamped publishers#213hijimasa wants to merge 2 commits into
Conversation
Add a ContactSensor to the UnitySensors package that tracks active collisions via OnCollisionEnter/Stay/Exit. Unity delivers those messages to the GameObject holding the touched collider, so the sensor automatically relays events from collider-only children (via ContactEventRelay) and exposes RegisterCollider() for colliders outside the default scan. Per sampling tick it exposes whether any contact is active, the list of active contacts (collider name, position, normal, force estimated from Collision.impulse), and the net contact force/torque, both in world and sensor-local frames. The ROS serializers bind to new generic interfaces rather than the contact sensor itself, so they stay reusable for future sensors: IBoolStateInterface (std_msgs/Bool, bumper-style state) and IWrenchInterface (geometry_msgs/WrenchStamped, a local-frame wrench - e.g. a future force-torque sensor). Both publishers follow the existing RosMsgPublisher/RosMsgSerializer pattern and use only message types shipped with ROS-TCP-Connector. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Unity delivers OnCollision* only to the GameObject carrying the Rigidbody or ArticulationBody, never to a collider-only child. The sensor assumed the opposite - "delivered to the GameObject that holds the touched collider" - and put relays on the children, so a sensor placed on a part that has no body of its own heard nothing at all. That is the normal case for URDF: a link attached by a fixed joint has no degree of freedom, so a simulator may well give it no body and let its colliders belong to the nearest ancestor. A bumper plate bolted to a chassis is exactly this, and it silently reported no contact ever. RegisterBodyRelay() subscribes the sensor to another GameObject's collisions, and RegisterOwnCollider() says which colliders are the sensor's own. Once any is declared, contacts elsewhere on the shared body are dropped - without that a sensor on one plate would fire whenever any part of the whole assembly touched anything. UpdateContact now walks every contact point rather than only the first, because one Collision can carry points on several of the body's colliders and only some may be ours. Where only part of them are, the reported force is the pair impulse scaled by their share; the impulse is not available per point. Verified in a scene with two collider-only children under one ArticulationBody: the body GameObject receives the callbacks (the children receive none), and ContactPoint.thisCollider names the child that was touched, so the filter has something to key on. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Pushed a follow-up commit. The sensor reported nothing on a link whose colliders belong The first version assumed OnCollision* reaches the GameObject holding the touched Added:
Verified with two collider-only children under one Callbacks go to the body, children get nothing, and Caveat: |
Summary
This PR adds a contact (bumper) sensor to UnitySensors, following the existing sensor architecture (one small, self-contained sensor per PR). It detects collisions on the body it is attached to and publishes bumper-style contact state and the net contact wrench to ROS 2.
Purely additive: no existing files are modified except the sensor list in README.md, and no asmdef or dependency changes are needed.
Design
Core (Packages/UnitySensors)
ROS (Packages/UnitySensorsROS)
Validation
Tested end-to-end inside a ROS 2 (Humble) robot simulator built on this package (Unity 6000.3, Linux player): a 1 kg box with a contact sensor spawned 0.5 m above the ground —
Out of scope (possible follow-ups)