Skip to content

feat(scenario): multi-agency-sar scenario with vendor-tinted chassis - #9

Merged
WomB0ComB0 merged 2 commits into
mainfrom
feat/multi-agency-sar
Apr 20, 2026
Merged

WomB0ComB0 merged 2 commits into
mainfrom
feat/multi-agency-sar

Conversation

@WomB0ComB0

Copy link
Copy Markdown
Member

Summary

First slice of the multi-agency coordination demo (item #1 in the polish plan). End-to-end vendor tagging — scenario config → simulation service → viz frame → client rendering — plus a new multi-agency-sar preset with 12 drones across 3 vendors (4 each: skydio, autel, anzu).

Why

The coordination narrative is "ten agencies show up with different drones and one shared air picture." To show that without narration, drones need to be visibly differentiated while remaining silhouette-consistent. Chassis top-plate tint per vendor delivers the signature without disturbing the swarm read.

What changed

Backend

File Change
Models/VizFrame.cs Optional Vendor on DroneVizState
Services/SimulationService.cs New AddDrone(id, pos, vendor) overload. Sidecar _droneVendors dict keyed by id. Reset() clears. GetSnapshot() populates DroneSnapshot.Vendor.
Services/VizFrameBuilder.cs Propagates vendor to frame
Services/ScenarioService.cs Public Entry(Id, Pos, Vendor?) record struct; parses optional vendor field from config
appsettings.json multi-agency-sar scenario (12 entries, 3 vendors)

Client

File Change
client/types.ts DroneState.vendor?: string
client/drones.ts VENDOR_COLORS map + bodyColor param on _buildQuadrotor. Top-plate tinted by vendor.

Colors (subtle — silhouette preserved):

  • skydio → steel-blue #2b3a55
  • autel → deep oxblood #5a2a30
  • anzu → dark forest #2a4a36
  • Unmapped / absent → existing BODY_COLOR #161b22

Backwards compat

Purely additive at every layer:

  • DroneVizState.Vendor defaults to null
  • DroneSnapshot.Vendor defaults to null
  • AddDrone(id, pos) overload preserved; forwards to AddDrone(id, pos, null)
  • DroneState.vendor is optional in the TS interface
  • Existing scenarios (single, swarm-5, swarm-20, sar) load unchanged

Deferred to follow-up PRs (kept scope tight)

  • Kill-comms REST endpoint + Mesh.Partitioned signal
  • Partition status banner (client)
  • Scenario intro overlay (HURRICANE MELISSA toast)
  • Vendor-specific LED signatures (overlaps with polish item ci: add placeholder required status gate #4 — LED state-machine)

Local verification

tsc --noEmit                                   → clean
vite build (via Release MSBuild)               → green
dotnet build ResQ.Viz.sln -c Release           → 0 Warning(s) / 0 Error(s)
dotnet format --verify-no-changes --severity warn → exit 0
dotnet test  -c Release                        → 82 / 82 passing

Test plan

  • Run the server, pick multi-agency-sar from the scenarios list
  • 12 drones spawn in 3 clusters (W / E / N)
  • Chassis tint is visible per vendor without breaking the swarm's visual cohesion

🤖 Generated with Claude Code

First slice of the multi-agency coordination demo (#1 in the polish
plan). Adds end-to-end vendor tagging — scenario config → simulation
service → viz frame → client rendering — and a new `multi-agency-sar`
preset with 12 drones across 3 vendors (skydio / autel / anzu, 4 each).

Changes:
* `Models/VizFrame.cs` — optional `Vendor` on `DroneVizState`
* `Services/SimulationService.cs` — new `AddDrone(id, pos, vendor)`
  overload; sidecar `_droneVendors` dict cleared on `Reset()`;
  `DroneSnapshot.Vendor` populated from dict in `GetSnapshot()`
* `Services/VizFrameBuilder.cs` — propagate vendor to frame
* `Services/ScenarioService.cs` — public `Entry(Id, Pos, Vendor?)` record
  struct; parse `vendor` from appsettings
* `appsettings.json` — `multi-agency-sar` scenario with 12 entries
* `client/types.ts` — `DroneState.vendor?: string`
* `client/drones.ts` — `VENDOR_COLORS` map + `bodyColor` param on
  `_buildQuadrotor`; top-plate tinted by vendor (subtle, silhouette
  preserved: skydio steel-blue, autel oxblood, anzu forest)

Deferred to follow-ups (kept scope tight):
* Kill-comms REST endpoint + `Mesh.Partitioned` signal
* Partition status banner (client)
* Scenario intro overlay (HURRICANE MELISSA toast)

Verified: tsc clean, vite build green, `dotnet build -c Release` green,
`dotnet format --verify-no-changes` clean, 82 / 82 tests passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@WomB0ComB0 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 8 minutes and 3 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 8 minutes and 3 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b8be36f4-8df4-4fd9-b3af-1e77356aba62

📥 Commits

Reviewing files that changed from the base of the PR and between 387e5c0 and 5518d68.

📒 Files selected for processing (7)
  • src/ResQ.Viz.Web/Models/VizFrame.cs
  • src/ResQ.Viz.Web/Services/ScenarioService.cs
  • src/ResQ.Viz.Web/Services/SimulationService.cs
  • src/ResQ.Viz.Web/Services/VizFrameBuilder.cs
  • src/ResQ.Viz.Web/appsettings.json
  • src/ResQ.Viz.Web/client/drones.ts
  • src/ResQ.Viz.Web/client/types.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/multi-agency-sar

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces vendor-specific branding for drones in the visualization. It adds a Vendor property to drone state models and configuration, allowing the client to render unique chassis tints for different agencies (e.g., Skydio, Autel, Anzu). Key changes include updating the ScenarioService to parse vendor tags, modifying SimulationService to track this metadata, and updating the Three.js client to apply vendor-specific colors. Feedback suggests using string.IsNullOrWhiteSpace for more robust configuration parsing and considering a more comprehensive lifecycle management for drone metadata to prevent potential memory leaks if dynamic drone removal is implemented in the future.

Comment thread src/ResQ.Viz.Web/Services/SimulationService.cs
Comment thread src/ResQ.Viz.Web/Services/ScenarioService.cs Outdated
Per review: `IsNullOrEmpty` accepts whitespace-only strings from
appsettings (e.g. `"vendor": "  "`) which would then become a dictionary
key and flow into the viz frame. Swap to `IsNullOrWhiteSpace` so the
parser is consistent with normal IConfiguration handling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@WomB0ComB0

Copy link
Copy Markdown
Member Author

Thanks for the review — pushed 5518d68 to address the IsNullOrWhiteSpace suggestion. On the _droneVendors lifecycle point: no drone-removal pathway exists today (SimulationService only supports bulk Reset(), which already clears the dict), so no leak is possible in the current codebase. If per-drone removal is added later, the dict cleanup should be wired in the same hook — noted for that future change.

@WomB0ComB0
WomB0ComB0 merged commit 07ed15a into main Apr 20, 2026
35 checks passed
@WomB0ComB0
WomB0ComB0 deleted the feat/multi-agency-sar branch April 20, 2026 06:26
WomB0ComB0 added a commit that referenced this pull request Apr 20, 2026
Item #9 of the polish plan. The meta copy still framed the product as
"Drone Simulation Visualizer" — old framing from before the coordination
story. Aligns title, description, Open Graph, and Twitter card metadata
with the current positioning:

  title       "ResQ Viz — Live Coordination"
  description "Real-time 3D coordination across autonomous drone swarms
               — mesh topology, hazard fusion, and decentralized
               consensus for disaster response."

Shipped as copy-only change. Existing OG setup (summary_large_image,
canonical, theme-color, emoji-placeholder favicon) unchanged — the
proper ResQ OG banner and logo favicon are a separate asset swap.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
WomB0ComB0 added a commit that referenced this pull request Apr 20, 2026
* docs(meta): align title + description with coordination narrative

Item #9 of the polish plan. The meta copy still framed the product as
"Drone Simulation Visualizer" — old framing from before the coordination
story. Aligns title, description, Open Graph, and Twitter card metadata
with the current positioning:

  title       "ResQ Viz — Live Coordination"
  description "Real-time 3D coordination across autonomous drone swarms
               — mesh topology, hazard fusion, and decentralized
               consensus for disaster response."

Shipped as copy-only change. Existing OG setup (summary_large_image,
canonical, theme-color, emoji-placeholder favicon) unchanged — the
proper ResQ OG banner and logo favicon are a separate asset swap.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(meta): restore trailing copy on twitter:description

Per review: twitter:description was truncated. Spec is that it matches
the primary description and og:description verbatim; Twitter's 200-char
limit has plenty of room. Restore the trailing "for disaster response.".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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