Rocky (VSG geospatial): terrain physics (RockyGround) + map rendering (SceneRockyVisualizer)#1121
Rocky (VSG geospatial): terrain physics (RockyGround) + map rendering (SceneRockyVisualizer)#1121tabgab wants to merge 8 commits into
Conversation
Detailed, phased, implementable plan for running INET sims on real geospatial data (imagery + elevation) via Pelican Mapping's Rocky (the VSG successor to osgEarth). Mirrors INET's existing OSG geospatial trio (SceneOsgEarthVisualizer / OsgEarthGround / IGeographicCoordinateSystem) for VSG. Front-loads two de-risking spikes (macOS/MoltenVK build; Rocky rendering under our off-screen VSG path) with GO/NO-GO gates and a physics-first fallback that reuses the LIDAR Heightfield + ground-mesh render if live Rocky rendering proves infeasible off-screen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…sgEarth successor) New IGround backed by the Rocky SDK: opens a GDAL-openable elevation source (e.g. a GeoTIFF DEM) and samples it with rocky::ElevationSampler, converting scene<->geographic through an IGeographicCoordinateSystem — the same pattern as OsgEarthGround, but headless and OSG-free. So TwoRayGroundReflection and any other IGround consumer work over real terrain with no changes to them. Build wiring in src/makefrag: a WITH_ROCKY option (off by default) adds Rocky's include/lib (ROCKY_ROOT prefix) and defines WITH_ROCKY via a -D flag kept in the same CFLAGS as the include path. INET builds unchanged with WITH_ROCKY unset. Verified on macOS/arm64 against VSG 1.1.15 / Vulkan 1.4.350 / MoltenVK: librocky links into libINET, and the examples/environment/rockyground smoke test runs headlessly — RockyGround opens a DEM and returns the correct ground elevation at sampled scene points in a live simulation. DEV NOTES (for upstreaming): ROCKY_ROOT is a hardcoded local prefix (use pkg-config/a configure check instead); Rocky itself currently needs three local source patches on macOS (a GDAL 3.13 CSLConstList fix, ImGui-off build guards, and a CoreFoundation/Security link line) that should go upstream to pelicanmapping/rocky. A .oppfeatures feature and the live-map SceneRockyVisualizer (needs an omnetpp-dev viewer hook) are follow-ups. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… 3D view Renders real geospatial imagery + terrain in Qtenv's VSG view using Rocky (the VSG successor to osgEarth), the rendering counterpart to RockyGround's physics. Extends SceneVsgVisualizer, so all the usual scene setup still applies; on top of it the Rocky map is built against the live vsg::Viewer and placed under the nodes. How it works: - The OSG plugin pages terrain from the OSG viewer's own frame loop; Rocky (VSG) instead needs the live viewer (to build a VSGContext) and an explicit per-frame update() to page/compile tiles. Both come through the VsgScene3DNode render hook the backend now publishes (omnetpp-dev): onViewerChanged -> (re)build the map; a per-frame callback -> vsgcontext->update(). - Layers are GDAL files (imageFile/elevationFile) and/or online TMS endpoints (imageUrl/elevationUrl, e.g. readymap.org), so it works offline from a local GeoTIFF or streams real Earth tiles over the network. - Rocky's geocentric (ECEF) map is transformed into the scene's local ENU frame, anchored at an IGeographicCoordinateSystem's origin, so it sits under the nodes. - ROCKY_FILE_PATH (rockyResourcePath) is set so Rocky finds its shaders. examples/visualizer/vsgrocky: RockyMapShowcase with a synthetic-tile [General] config (offline) and a [Config RealMap] that streams San Francisco Bay imagery + elevation from readymap.org. Verified on macOS/arm64: real Earth imagery + terrain render in Qtenv, hosts georeferenced on the map, no teardown crash. KNOWN LIMITATIONS (navigation, not physics): the generic orbit camera fights Rocky's globe-oriented tile paging, so zoomed-out framing and tile LOD are rough; node billboards show the clear colour in their background. Both are follow-ups; the geospatial rendering itself works. Needs INET built with WITH_ROCKY=yes and the omnetpp-dev VSG viewer hook. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Set the camera manipulator to OVERVIEW so the Rocky map opens looking straight down and stays top-down through wheel zoom, so panning out shows more map rather than the horizon (with the omnetpp-dev fix that honors the manipulator on the initial view). Pairs with the sky-colour backdrop already set here. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- SceneRockyVisualizer: insert the map at the FRONT of the scene so the opaque terrain draws before the transparent node icons; otherwise the icons write depth that occludes the map in their billboard quad and their transparent pixels show the background clear colour instead of the map. - examples/visualizer/vsgrocky: add a [Config Communication] where three hosts actually exchange UDP traffic over the real map (idealized unit-disk radios, deterministic 4 km range) with the radio signals, communication ranges and packet route drawn on the map. Make the network's radioMedium swappable (like IRadioMedium) so the config can select the idealized medium. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The idealized unit-disk radio does not produce the transmission waveform the medium visualizer's signal spheres animate, and the config was missing signalWaveShader entirely - so no spheres appeared. Switch the Communication config to the same wireless + visualizer recipe as the vsglidar drone demo, whose spheres render correctly: realistic 802.11 ad-hoc radios (the network's default Ieee80211ScalarRadioMedium + Ieee80211MgmtAdhoc, transmit power boosted to bridge the ~1 km node spacing) and signalWaveShader = true, with signalFadingDistance / signalWaveLength scaled up so the pulsing spheres are sized for the km-scale map. Hosts moved into a ~800 m triangle so all links are in range. Verified: host3 receives host1's UDP packets and the signal spheres render over the map. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fixes found in code review: - Guard the callbacks registered on the (parent-owned, longer-lived) VsgScene3DNode with a shared 'alive' flag, cleared in a new destructor, so they no-op instead of using freed memory after the visualizer submodule is destroyed (submodules are destroyed before their parent -> use-after-free). - In the resize/rebuild path, release the old MapNode BEFORE recreating the VSGContext it depends on (the old code destroyed the context/device while the old map's GPU resources were still alive -> Vulkan validation error/leak). - Clearer error when the canvas has no 3D scene at all vs. a wrong backend. - Document the ellipsoidal-map vs. flat-SimpleGeographicCoordinateSystem projection mismatch that grows with distance from the origin. Add ROCKY-VSG-GUIDE.md: a developer guide covering RockyGround (terrain physics), SceneRockyVisualizer (map in the 3D view), the VsgScene3DNode render hook for custom Rocky visualizations, and the gotchas (topocentric/WGS84/cull-radius, ROCKY_FILE_PATH, no raw VSG lines off-screen, the projection caveat). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| # DEV NOTE: ROCKY_ROOT below is a local development default; for upstreaming, resolve | ||
| # it via pkg-config / a configure check instead of a hardcoded path. | ||
| WITH_ROCKY ?= no | ||
| ROCKY_ROOT ?= /Users/gabortabi/rocky-install |
There was a problem hiding this comment.
🔍 Developer-specific hardcoded path in makefrag default
The ROCKY_ROOT default at src/makefrag:89 is set to /Users/gabortabi/rocky-install, a developer-specific macOS path. While it uses ?= (overridable) and has a comment acknowledging it's a "local development default", this should be cleaned up before merging to avoid confusion. Other optional dependencies in this file (VoipStream, Z3) use pkg-config or system defaults rather than hardcoded developer paths.
Was this helpful? React with 👍 or 👎 to provide feedback.
| *.visualizer.sceneVisualizer.coordinateSystemModule = "^.^.coordinateSystem" | ||
| *.visualizer.sceneVisualizer.imageFile = "img.tif" | ||
| *.visualizer.sceneVisualizer.elevationFile = "dem.tif" | ||
| *.visualizer.sceneVisualizer.rockyResourcePath = "/Users/gabortabi/rocky-install/share/rocky" |
There was a problem hiding this comment.
🔍 Same developer-specific path hardcoded in example ini
The rockyResourcePath at line 16 is hardcoded to /Users/gabortabi/rocky-install/share/rocky. This will fail for any other developer or CI system. Consider using an environment variable fallback or a relative path, or at minimum documenting that this must be changed.
Was this helpful? React with 👍 or 👎 to provide feedback.
- src/makefrag: ROCKY_ROOT defaults to pkg-config's prefix or /usr/local instead of a developer-specific path, and is meant to be overridden on the command line; add a friendly $(error) when WITH_ROCKY=yes but the Rocky SDK is not found under ROCKY_ROOT (instead of a cryptic compiler failure). - examples/visualizer/vsgrocky: drop the hardcoded rockyResourcePath; document setting the ROCKY_FILE_PATH environment variable instead (portable / CI-safe). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Thanks — both valid, fixed in bbf9915:
The same personal paths existed in the companion omnetpp-dev PR (the |
Adds real geospatial capability to INET via Rocky (the VulkanSceneGraph successor to osgEarth): real terrain elevation in the radio physics, and a real geospatial map rendered in the VSG 3D view.
RockyGround— terrain physics (headless)An
IGroundbacked by a GDAL-openable elevation source (a GeoTIFF DEM, …), sampled withrocky::ElevationSampler. Any consumer ofphysicalEnvironment.getGround()— e.g.TwoRayGroundReflectionpath loss — then sees the real surface with no changes to that consumer. Needs no viewer, so it runs in Cmdenv. Example:examples/environment/rockyground.SceneRockyVisualizer— map in the 3D viewRenders a Rocky map (local GDAL files or online TMS tiles, e.g. readymap.org) in the Qtenv VSG 3D view, transformed into the scene's local ENU frame under the network nodes. Uses the
VsgScene3DNoderender hook from the companion omnetpp-dev PR. Example:examples/visualizer/vsgrocky—General(offline synthetic tile),RealMap(readymap San Francisco Bay),Communication(nodes exchanging UDP over the map, with signal spheres + packet routes).Build
Opt-in
WITH_ROCKYinsrc/makefrag(off by default — INET builds unchanged without it). Build withmake WITH_ROCKY=yes ROCKY_ROOT=/path/to/rocky-install.Docs
ROCKY-VSG-GUIDE.md— a developer guide covering both modules, building your own Rocky visualizations via the render hook, and the gotchas (topocentric/WGS84/cull-radius,ROCKY_FILE_PATH, the projection caveat).Dependencies / stacking
feature/vsg-viewer-hook).vsg-lidar-pathloss) → visualizer/osg: fix build against omnetpp topic/VSG (osg::Node fwd-decl removed from cenvir.h) #1118 → visualizer: adopt backend-neutral cScene3DNode (OSG+VSG coexistence) #1116 (OSG/VSG coexistence). Targets LIDAR terrain drives RF path loss / occlusion (PointCloudGround, TerrainObstacleLoss, ground-mesh render) #1120's branch so it shows only the Rocky commits — review/merge those first (or retarget as preferred).A code-review pass fixed two use-after-free hazards (callbacks outliving the module; context destroyed before the map it owns) and documented a known limitation (the flat
SimpleGeographicCoordinateSystemvs. the ellipsoidal map placement drifts with distance from the origin — a map-SRS-derived coordinate system would remove it).