multi-robot support with parallel spawn#294
Conversation
javizqh
left a comment
There was a problem hiding this comment.
Review every single one of the changes. Right now it is not mergeable
| @@ -1,3 +1,4 @@ | |||
| import re | |||
| from gz.transport13 import Node | ||
|
|
||
|
|
||
| def _find_drone_namespaces(): |
| # reset the AS2 state machine for every drone that's up (not just drone0). | ||
| # _find_drone_namespaces returns [] for non-drone exercises, so this is | ||
| # a no-op there and only the world reset below runs. | ||
| for ns in _find_drone_namespaces(): |
| 10000, | ||
| ) | ||
|
|
||
| # reset each drone's controller too (not just drone0) |
| except Exception as e: | ||
| LogManager.logger.exception(f"Error refreshing GTK applications: {e}") | ||
|
|
||
| def _kill_all_applications(self): |
There was a problem hiding this comment.
Remove this function and add it inline where it should go. Functions for 1 line are not needed
| to_lint = app_cfg["linter"] | ||
|
|
||
| # Unzip the app | ||
| # the code comes as a base64 data-uri from the browser, strip the header part |
There was a problem hiding this comment.
Why change the comments. Must be reverted
| try: | ||
| stop_process_and_children(self.application_process) | ||
| self.application_process = None | ||
| # Pause sim first — freezes Gazebo physics immediately so every |
| ) | ||
| except Exception as e: | ||
| LogManager.logger.exception("Exception terminating scene launcher") | ||
| # relaunch all robots (in parallel) so they respawn at their start pose |
b3291f8 to
8583162
Compare
|
hi @javizqh requested chnages were done please review once |
There was a problem hiding this comment.
Extra config does not need to be stored
| extra_config = "" | ||
|
|
||
| # pass the entity name to the launch. entity is the gazebo model name | ||
| # (used to spawn/remove the model); the launch file decides how to use it |
| self.world_type = None | ||
| self.robot_launcher = None | ||
| self.robot_config = None | ||
| # one launcher per robot (a list, so N robots are supported the same way |
There was a problem hiding this comment.
Remove irrelevant comment. It is clear that a list of robot launchers is a list of robots launchers
| self.robot_launcher.run( | ||
| robot_cfg["entity"], robot_cfg["start_pose"], robot_cfg["extra_config"] | ||
| ) | ||
| self._run_all_robots() |
| with open("/workspace/code/app.zip", "wb") as result: | ||
| result.write(base64.b64decode(code)) | ||
|
|
||
| # just extract evrything to /workspace/code — if theres a processB/ folder |
There was a problem hiding this comment.
Incorrect. Entrypoints is a list and it decides where are the executables
| ) | ||
| except Exception as e: | ||
| LogManager.logger.exception("Exception terminating scene launcher") | ||
| # relaunch all robots (in parallel) so they respawn at their start pose |
|
hi @javizqh this is regarding the previous comment "Incorrect. Not all cfgs have a launcher" originally i had two parallel lists ( to fix that i dropped so the two comments pull in opposite directions: if i don't store the config on the i think the shape that closes both is a single list of pairs, so nothing is stored on that drops |
|
There can be cases where there is no robot assign to a world, so the robot_cfg has a dummy value instead of a real one. In that case it does not have a launcher |
|
you're right, thanks — i was only thinking about the case where every config is a i've restructured it so the two can't drift: the launcher and the config that no zip, no parallel lists, and |
|
This and the comment above are the same. The problem is that you are missing a simple if statement |
|
ah, got it — i was overcomplicating this. you're right, it's just an if. |
8583162 to
c8465a2
Compare
|
hi @javizqh requesting a review please pardon for any repeated ones as my local and upstream are litlle messed up. |
|
@anishk85 are you using an LLM to write the comments here, the use of -- and reply patterns are strange? If you are doing so, please refrain from doing it any longer |
Hey, just wanted to clarify something. I don't use any LLM to write my comments. The difference you might notice is mostly because I switch between my phone and my laptop When I'm replying from my phone (like I did this time), I have the Grammarly keyboard turned on It automatically fixes grammar, punctuation, and sometimes even rephrases things a little, so the message can end up looking more polished than how I'd normally type. The only reason I use Grammarly on my phone is because typing on a small keyboard is annoying and it's easy to make mistakes. It saves me from constantly fixing typos, especially when I'm having work-related or formal conversations on the go. When I'm on my laptop, I usually just type everything myself, so my writing is a bit different. You'll probably notice the same kind of variation in my Slack messages too—it really just depends on which device I'm using at the time. |
|
Okay, noted. Since I can't change it now from my phone at the moment due to some constraints, I'll reply to the GitHub thread from my laptop. |
|
Okay, no problem with that. Just, check the comment before sending it, I do not have the time to read a lot of comments and if they are nonsensical I lose even more time |
multi-robot support with parallel spawn
the manager now handles n robots instead of just one, and they spawn in parallel.
what changed
launch, reset, pause and teardown just loop over it — the state machine is
untouched and doesn't know there's more than one robot.
robotin the launch config is now an array (single-robot exercises arejust a list of one). an old single-object
robotstill works.entityname, passed to its launch file asentity:=andused as the ros/gazebo namespace, so n robots get their own
cmd_vel,odom,cameraand never collide.parallel spawn
before, each robot's
run()started the launch and then blocked polling gazebountil it appeared — so robots came up one after another. reset respawns the whole
group, so every reset paid the same cost.
we tried threading it earlier and it hung: the gz spawn-poll is a blocking call
that holds the gil, so the threads just starved each other.
so instead of threads, it's split in two:
run()only starts the launch and returnswait_spawned()does the spawn-poll, on the main thread_run_all_robots()starts all the launches, then waits for all of themthe launches run as separate processes, so the group comes up in about one spawn
time instead of n — and reset gets the same speed-up for free.
reset
reset kills every robot launcher, removes each entity from gazebo, resets the
world, then relaunches the group. gazebo's world reset wipes runtime-spawned
entities (and resetting a live one directly segfaults), so respawning is the
right way.