Repository navigation
Collisions, pillars and their octomap, tether task, ground go_to, config folders, student README - #2
Merged
Merged
Conversation
UNTESTED in the running sim: unit tests and the launch smoke test pass,
but nothing has been driven against the map in RViz yet.
At startup the ground robot sim and the Crazyflie server each read the
scenario's .bt octomap directly, keep the occupied voxels overlapping
sim.collision_z (default 0.2-2.0 m: trunks and posts, not the floor,
ceilings or tree canopies) and flatten them into one 2D grid with a
precomputed clearance per cell.
Each robot is a circle of its radius (scout 0.42, herover 0.17, other
ground robots 0.3, Crazyflies 0.1; `radius:` overrides). Every move is
checked along its path and stops before the circle touches an obstacle;
height changes always go through. set_position stays an unchecked
teleport. A robot spawned inside an obstacle can only move out of it.
On by default; sim: {collision: false} turns it off.
Known conflicts with existing scenarios:
- hero_mrs_control_stack test_branch: approach points of perch_b1 and
perch_b10 sit on icuas26_1 trunks, so drones can't reach them.
- config/herover.yaml: herover_4 spawns inside a trunk (warned at launch).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On hardware the mocap markers sit on top of the scout and herover, so their poses report that height, not 0. The control stack adds a body-frame dock's z to its host's z, so docks on a UGV were lower in the sim than on hardware. Ground robots now take pose.z, published on /<name>/pose and in the world -> <name> TF. It defaults by model to the top of the deck in the mesh: scout 0.227, herover 0.095, robots without a model 0. The RViz mesh is shifted down by z so it stays on the floor. Not run: the pytest suite (docker run interrupted). Scenario parsing was checked on the host. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A winch drags an object across the floor; the tether runs through a pulley on a ground robot and a ring on a Crazyflie. A scenario sets it up with an optional tether: section (config/tether_demo.yaml). Without one, nothing extra runs. - hero_sim/tether.py: ROS-free quasi-static model. Slack leaves the object, taut slides it toward the point under the UAV, it is never lifted, and it jams against pillars; the winch slips in both cases. - hero_sim/tether_sim.py: node publishing /winch/* and /tether/* plus RViz markers, started by sim.launch.py only for a tether: section. - config: validated tether: section, documented in README and example.yaml; RViz gets a Tether display. - Tests for the model, config and node; CI smoke tests check tether_sim starts with a tether: section and not without one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r object Pillars move from tether.obstacles to a top-level obstacles: list and live in the same ObstacleMap as the octomap grid (kept as exact circles, also with map: null). Ground robots, Crazyflies (at any height) and the tether object all stop at the same obstacles, under the one sim.collision switch. ground_robot_sim publishes the pillars latched on /hero_sim/obstacles (one CYLINDER each), drawn by a new Obstacles display in sim.rviz. tether.obstacles now fails with a pointer to the new key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every ground robot serves /<name>/go_to with crazyflie_interfaces/srv/GoTo, the Crazyflies' type. It reaches goal x, y and yaw in `duration`, stretched to stay within ground_max_speed and ground_max_yaw_rate (duration 0: as fast as allowed). omni drives straight while turning; diff turns, drives, then turns (kinematics.GroundGoTo). relative offsets x, y in the world frame; goal.z and group_mask are ignored. Any cmd_vel cancels it, and it stops at the map and pillars like every other move. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Under sim.collision, each ground robot's move is checked against the other ground robots as circles of their radius, in the same pass as the map and the pillars (ObstacleMap.move's new `others`). Robots move one after another each tick against the others' current positions, so they never overlap; radius 0 opts out. load() now returns an empty map without a map or pillars, so this works in bare scenarios too. A blocked go_to now waits where it stopped, its clock paused, and carries on once the way clears, instead of jumping to where its schedule got to. config/two_ugvs.yaml: two herovers and the tether demo's pillar, no tether. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… size Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Configs can sit in config/ or a folder in it: tether/ for the tether task, mrs/ for the control stack's Crazyflie scenarios, the rest on top (example, ground-robot-only setups). A bare filename is searched in every folder (names are unique; two matches are an error), folder/name.yaml is relative to config/ unless it's an existing path. Same rules in config.find_config (launch files, nodes) and startup/_setup.sh. setup.py installs the folders and skips the broken links a --symlink-install build keeps to moved configs, so existing workspaces rebuild without a clean. Tests cover both resolvers and run every config in every folder. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Setup, start/stop, scenarios and folders, moving the robots, obstacles, the tether task and troubleshooting, without the internals. Every command in it was run against the sim. Mesh-making notes move to models/README.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds the sim_env_a / sim_env_a12 experiment scenarios, the test_perching_full(2) and test_unperch scenarios to config/mrs/, moves dock_hardware2 there, and makes test_perching_full2 the default. The example scenario gets its pillar, sim.rviz the current view, and the README's tether section the task diagram (media/tether_demo.png). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… or obstacles With obstacles:, octomap.launch.py writes the pillars as an octomap .bt (<tmp>/hero_sim/<config>_obstacles.bt, floor to each pillar's height, no ground plane) and serves it with octomap_server like a sim.map, so RViz shows the same occupied cells, projected map and topics. obstacles.write_bt is read_bt's inverse. Pillars take an optional height (default 2 m) for RViz and the octomap; collisions still ignore it. A scenario sets sim.map or obstacles:, not both: obstacles drop the default map, and setting both is an error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README: one Maps section for the two kinds of world, a .bt map or obstacles:, what each looks like in RViz and where the pillar map file goes, instead of the scattered mentions. sim.rviz: the occupied-cells displays subscribe Transient Local, as octomap_server publishes the map once, latched. RViz started after the octomap now still draws it, so session.yml needs no sleep before it. example.yaml: the pillar commented out again, so the example uses the default map. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…only The example scenario uses its pillar (no map) again. sim.rviz hides the pillar cylinders by default, which showed through the octomap cells; the Obstacles display can still be ticked on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
sim.collision_z, flattened), at pillars, and ground robots at each other. Drones are blocked at any height and don't collide with ground robots or each other. One switch:sim.collision.obstacles:list,{x, y, radius, height}. They block the robots and the tether object, are published latched on/hero_sim/obstacles, and are turned into an octomap thatoctomap_serverserves like a.btmap (same topics, same look in RViz). A scenario hassim.maporobstacles:, not both.config/tether/tether_demo.yaml./<name>/go_to(crazyflie_interfaces/srv/GoTo), held to the speed limits; omni drives straight, diff turns-drives-turns. Poses are published at the marker height.config/tether/,config/mrs/(Crazyflie scenarios) andconfig/. A config is found by filename in any folder (names are unique);start.sh, the launch files and the nodes share the rules.models/README.md.Heads-up
tether.obstaclesmoved to the top-levelobstacles:; the old key fails with a pointer to the new one.config/<name>paths themselves need to search the folders too (e.g.hero_mrs_control_stack/sim_experiments/run_trial.py).--symlink-installworkspaces rebuild over the old layout as is. A plain install may keep stale copies:rm -rf build/hero_sim install/hero_sim, then build.go_toblocked by an obstacle or robot now waits and carries on once the way is clear; anycmd_velcancels it.Testing
icuas26_finalsimage; CI runs them withouthero_mrs_msgs(3 skip).go_tostops at a pillar and at another robot and resumes when it moves away;octomap_serverloads a generated pillar map (all 6240 cells, the same topics asicuas26_1.bt); RViz under Xvfb draws the map when started after the octomap; every command in the README runs as written.🤖 Generated with Claude Code