Skip to content

[FEATURE] Add ray_alignment and link exclusion to the raycaster. - #3280

Open
lupinjia wants to merge 3 commits into
Genesis-Embodied-AI:mainfrom
lupinjia:main
Open

[FEATURE] Add ray_alignment and link exclusion to the raycaster.#3280
lupinjia wants to merge 3 commits into
Genesis-Embodied-AI:mainfrom
lupinjia:main

Conversation

@lupinjia

@lupinjia lupinjia commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Description

This PR extends the raycaster with two capabilities that are common in legged-locomotion terrain perception:

  1. ray_alignment ("base" / "yaw" / "world") — controls how the ray grid is oriented relative to the sensor's frame link:
  • "base" (default): rays follow the link's full orientation.
  • "yaw": rays follow only the link's yaw (ignore pitch/roll), keeping the grid horizontal on slopes.
  • "world": rays are fixed in the world frame, independent of the link orientation.
  1. exclude_link_idx — global rigid link indices whose geometry the rays ignore. A ray that would hit a face owned by an excluded link reports no hit, so the scan passes through the robot's own links to read the terrain below. This is the behaviour a terrain height scan needs.
    Both features are applied per-sensor. ray_alignment is resolved at cast time by correcting the gathered link quaternion; exclude_link_idx is compiled into the ray-cast kernel as a per-sensor link mask, gated by a compile-time flag so non-filtering sensors pay no per-leaf cost.

Related Issue

None

Motivation and Context

Terrain perception for quadruped locomotion needs a downward height scan that (a) stays horizontal when the robot pitches/rolls on slopes (yaw/world) and (b) ignores the robot's own body so the scan reads the ground instead of the legs. Without these, a base-mounted grid raycast both tilts with the body and self-intersects the robot's geometry.

How Has This Been / Can This Be Tested?

Unit tests were added to tests/sensors/test_raycaster.py (run with the project's required CI command):
pytest -v --forked -m required ./tests/sensors/test_raycaster.py

  • test_ray_alignment — a carrier tilted 30 deg about x; asserts the base grid's hit-distance range is wider than the level yaw/world grids.
  • test_exclude_link_idx — asserts that excluding an obstacle's link removes the obstacle-top hit so the rays pass through to the ground.
    Two runnable examples demonstrate the features visually:
python examples/sensors/raycaster_alignment.py          # base/yaw/world under two-phase motion
python examples/sensors/raycaster_exclude_go2.py        # go2 self-exclusion for a terrain scan

Screenshots (if appropriate):

Checklist:

  • I read the CONTRIBUTING document.
  • I followed the Submitting Code Changes section of CONTRIBUTING document.
  • I tagged the title correctly (including BUG FIX/FEATURE/MISC/BREAKING)
  • I updated the documentation accordingly or no change is needed.
  • I tested my changes and added instructions on how to test it for reviewers.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ee678f72b4

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 714 to +716
kernel_cast_rays_visual(
*args_common,
raw_data_T,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply link exclusions to visual ray casts

When an excluded rigid link belongs to an entity with material.use_visual_raycasting=True, its collision faces are filtered but this visual-BVH branch receives no exclusion mask. The visual pass can therefore merge a hit from the excluded link back into the result, so exclude_link_idx does not actually make the sensor blind to all of that link's geometry. Pass the per-sensor exclusion data into the rigid visual traversal and filter via the visual geometry's owning link as well.

Useful? React with 👍 / 👎.

Comment on lines +105 to +110
pitch = math.radians(args.swing) * math.sin(2.0 * math.pi * 1.0 * t)
quat = euler_to_quat((pitch, 0.0, 0.0))
else:
# Phase 2: continuous yaw rotation about z.
yaw = math.radians(args.yaw_rate) * (t - args.phase1)
quat = euler_to_quat((0.0, 0.0, yaw))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pass degrees to the alignment demo quaternion helper

genesis.utils.geom.euler_to_quat interprets its input as degrees, but this example first converts args.swing and args.yaw_rate to radians. With the defaults, the advertised 60-degree swing is only about 1.05 degrees and the advertised 90-degree/s rotation is about 1.57 degrees/s, so the demo barely exhibits either alignment difference. Keep these values in degrees when calling the helper.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant