From e15b0367203878e366f833adec46726a884d084b Mon Sep 17 00:00:00 2001 From: Burak Ozter Date: Fri, 15 Nov 2024 11:35:47 -0400 Subject: [PATCH 1/6] add missing apt package ros-gz-image --- robots/spiri-mu/virtual_camera/Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/robots/spiri-mu/virtual_camera/Dockerfile b/robots/spiri-mu/virtual_camera/Dockerfile index ffbfbdc..69bb0af 100644 --- a/robots/spiri-mu/virtual_camera/Dockerfile +++ b/robots/spiri-mu/virtual_camera/Dockerfile @@ -1,5 +1,8 @@ FROM git.spirirobotics.com/spiri/services-ros2-mavros:main RUN apt-get update -RUN apt-get --yes install ros-${ROS_DISTRO}-ros-gz-bridge ros-${ROS_DISTRO}-compressed-image-transport ros-${ROS_DISTRO}-rmw-cyclonedds-cpp +RUN apt-get --yes install ros-${ROS_DISTRO}-ros-gz-bridge \ + ros-${ROS_DISTRO}-ros-gz-image \ + ros-${ROS_DISTRO}-compressed-image-transport \ + ros-${ROS_DISTRO}-rmw-cyclonedds-cpp -- 2.40.1 From f035a09321bc14091aa33ff0d08ab4f229f48d05 Mon Sep 17 00:00:00 2001 From: Alex Davies Date: Fri, 15 Nov 2024 12:52:27 -0400 Subject: [PATCH 2/6] Update for more reliable compose --- guiTools/spiri_sdk_guitools/launcher.py | 2 +- guiTools/spiri_sdk_guitools/sim_drone.py | 74 ++++++++++--------- .../virtual_camera/docker-compose.yaml | 5 +- 3 files changed, 46 insertions(+), 35 deletions(-) diff --git a/guiTools/spiri_sdk_guitools/launcher.py b/guiTools/spiri_sdk_guitools/launcher.py index 918f2cb..53e6082 100644 --- a/guiTools/spiri_sdk_guitools/launcher.py +++ b/guiTools/spiri_sdk_guitools/launcher.py @@ -70,7 +70,7 @@ async def main(): ).bind_value(newRobotParams, 'sysid') default_robot_compose = ( "/robots/spiri-mu/core/docker-compose.yaml\n" - "#/robots/spiri-mu/virtual_camera/docker-compose.yaml" + "#/robots/spiri-mu/virtual_camera/docker-compose.yaml --build" ) ui.label("Compose files").classes("text-xl") ui.codemirror(value=default_robot_compose, language="bash", theme="basicDark").bind_value(newRobotParams, 'compose_files') diff --git a/guiTools/spiri_sdk_guitools/sim_drone.py b/guiTools/spiri_sdk_guitools/sim_drone.py index c7f3d2b..d77713a 100644 --- a/guiTools/spiri_sdk_guitools/sim_drone.py +++ b/guiTools/spiri_sdk_guitools/sim_drone.py @@ -96,38 +96,39 @@ class Robot: container_status = {} with element: while True: - # Poll for data that changes - for container in self.containers(): - try: - health = container.attrs["State"]["Health"]["Status"] - except KeyError: - health = "Unknown" + with logger.catch(): + # Poll for data that changes + for container in self.containers(): + try: + health = container.attrs["State"]["Health"]["Status"] + except KeyError: + health = "Unknown" - container_status[container] = ( - f"{container.name} {container.status} {health}" - ) - if container not in docker_elements: - docker_elements[container] = ui.element().classes("w-full") - with docker_elements[container]: - ui.label().bind_text(container_status, container).classes( - "text-lg" - ) - #Show the command the container is running - # ui.label(container.attrs["Config"]["Cmd"]) - cmd_widget = ui.codemirror(" ".join(container.attrs["Config"]["Cmd"]), language="bash",theme="basicDark").classes('h-auto max-h-32') - cmd_widget.enabled = False - logelement = ( - ui.expansion("Logs") - .style("margin: 10px;") - .classes("w-full outline outline-1") - ) - asyncio.create_task(container_logs(container, logelement)) - # Check for containers that have been removed - removed = set(docker_elements.keys()) - set(self.containers()) - for container in removed: - self.robot_ui.remove(docker_elements[container]) - docker_elements.pop(container) - await asyncio.sleep(1) + container_status[container] = ( + f"{container.name} {container.status} {health}" + ) + if container not in docker_elements: + docker_elements[container] = ui.element().classes("w-full") + with docker_elements[container]: + ui.label().bind_text(container_status, container).classes( + "text-lg" + ) + #Show the command the container is running + # ui.label(container.attrs["Config"]["Cmd"]) + cmd_widget = ui.codemirror(" ".join(container.attrs["Config"]["Cmd"]), language="bash",theme="basicDark").classes('h-auto max-h-32') + cmd_widget.enabled = False + logelement = ( + ui.expansion("Logs") + .style("margin: 10px;") + .classes("w-full outline outline-1") + ) + asyncio.create_task(container_logs(container, logelement)) + # Check for containers that have been removed + removed = set(docker_elements.keys()) - set(self.containers()) + for container in removed: + self.robot_ui.remove(docker_elements[container]) + docker_elements.pop(container) + await asyncio.sleep(1) async def ui_ros(self, element): with element: @@ -221,6 +222,11 @@ class Robot: self.spawn_gz_model() logger.info("Starting drone stack, this may take some time") for compose_file in self.compose_files: + arguments = compose_file.split(" ") + arguments = [arg.strip() for arg in arguments] + compose_file = arguments[0] + arguments = arguments[1:] + if not isinstance(compose_file, Path): compose_file = Path(compose_file) if not compose_file.exists(): @@ -236,15 +242,17 @@ class Robot: "-f", compose_file.as_posix(), "up", + *arguments, ] command = " ".join(args) logger.info(f"Starting drone stack with command: {command}") docker_stack = subprocess.Popen( args, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + # stdout=subprocess.PIPE, + # stderr=subprocess.PIPE, ) + logger.info(f"Started drone stack with PID: {docker_stack.pid}") @logger.catch def spawn_gz_model(self): diff --git a/robots/spiri-mu/virtual_camera/docker-compose.yaml b/robots/spiri-mu/virtual_camera/docker-compose.yaml index 1969fd3..5a4bcf7 100644 --- a/robots/spiri-mu/virtual_camera/docker-compose.yaml +++ b/robots/spiri-mu/virtual_camera/docker-compose.yaml @@ -4,7 +4,10 @@ services: ipc: host network_mode: host # image: git.spirirobotics.com/spiri/services-ros2-mavros:main + #Build the iamge, give it a name, don't try to pull the image build: ./ + image: spirisdk-virtual_camera + pull_policy: never environment: - RMW_IMPLEMENTATION=rmw_cyclonedds_cpp - command: ros2 run ros_gz_image image_bridge /world/${WORLD_NAME}/model/${ROBOT_NAME}/link/pitch_link/sensor/camera/image \ No newline at end of file + command: ros2 run ros_gz_image image_bridge /world/${WORLD_NAME}/model/${ROBOT_NAME}/link/pitch_link/sensor/camera/image -- 2.40.1 From af170070ab3830725d148d7ba7935665f0b74e97 Mon Sep 17 00:00:00 2001 From: Alex Davies Date: Fri, 15 Nov 2024 12:59:31 -0400 Subject: [PATCH 3/6] Simplified ros topic filter --- guiTools/spiri_sdk_guitools/sim_drone.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guiTools/spiri_sdk_guitools/sim_drone.py b/guiTools/spiri_sdk_guitools/sim_drone.py index d77713a..aee195d 100644 --- a/guiTools/spiri_sdk_guitools/sim_drone.py +++ b/guiTools/spiri_sdk_guitools/sim_drone.py @@ -139,7 +139,7 @@ class Robot: scroll_area.clear() #Filter for topics that start with self.robot_name for topic in node_dummy.get_topic_names_and_types(): - if topic[0].startswith(f"/{self.robot_name}/") or topic[0].startswith(f"/world/{self.world_name}/model/{self.robot_name}/"): + if self.robot_name in topic[0]: ui.label(topic[0]) await asyncio.sleep(10) -- 2.40.1 From 43fead1589dbd0a6f822d1108c9a32dc42088c77 Mon Sep 17 00:00:00 2001 From: Alex Davies Date: Fri, 15 Nov 2024 13:11:47 -0400 Subject: [PATCH 4/6] Added more useful docker tools --- guiTools/spiri_sdk_guitools/sim_drone.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/guiTools/spiri_sdk_guitools/sim_drone.py b/guiTools/spiri_sdk_guitools/sim_drone.py index aee195d..f2eb508 100644 --- a/guiTools/spiri_sdk_guitools/sim_drone.py +++ b/guiTools/spiri_sdk_guitools/sim_drone.py @@ -6,6 +6,7 @@ import os import sh import subprocess from nicegui import ui, run, app +import yaml import docker import aiodocker @@ -117,12 +118,19 @@ class Robot: # ui.label(container.attrs["Config"]["Cmd"]) cmd_widget = ui.codemirror(" ".join(container.attrs["Config"]["Cmd"]), language="bash",theme="basicDark").classes('h-auto max-h-32') cmd_widget.enabled = False + + with ui.expansion("Env Variables").classes("w-full outline outline-1").style("margin: 10px;"): + env_widget = ui.codemirror("\n".join(container.attrs["Config"]["Env"]), language="bash",theme="basicDark") + env_widget.enabled = False + logelement = ( ui.expansion("Logs") .style("margin: 10px;") .classes("w-full outline outline-1") ) asyncio.create_task(container_logs(container, logelement)) + with ui.expansion("Full details").classes("w-full outline outline-1").style("margin: 10px;"): + details_widget = ui.codemirror(yaml.dump(container.attrs), language="yaml",theme="basicDark") # Check for containers that have been removed removed = set(docker_elements.keys()) - set(self.containers()) for container in removed: -- 2.40.1 From 271366bf7f076c1c3ae44349b20323cea3f8eca7 Mon Sep 17 00:00:00 2001 From: Alex Davies Date: Fri, 15 Nov 2024 13:14:26 -0400 Subject: [PATCH 5/6] Made robot container header larger --- guiTools/spiri_sdk_guitools/sim_drone.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guiTools/spiri_sdk_guitools/sim_drone.py b/guiTools/spiri_sdk_guitools/sim_drone.py index f2eb508..fa2c519 100644 --- a/guiTools/spiri_sdk_guitools/sim_drone.py +++ b/guiTools/spiri_sdk_guitools/sim_drone.py @@ -112,7 +112,7 @@ class Robot: docker_elements[container] = ui.element().classes("w-full") with docker_elements[container]: ui.label().bind_text(container_status, container).classes( - "text-lg" + "text-2xl" ) #Show the command the container is running # ui.label(container.attrs["Config"]["Cmd"]) -- 2.40.1 From 41493f935cff38c71408ccc311c57f4c34d19cf1 Mon Sep 17 00:00:00 2001 From: Alex Davies Date: Fri, 15 Nov 2024 13:15:09 -0400 Subject: [PATCH 6/6] Made detail widget uneditable --- guiTools/spiri_sdk_guitools/sim_drone.py | 1 + 1 file changed, 1 insertion(+) diff --git a/guiTools/spiri_sdk_guitools/sim_drone.py b/guiTools/spiri_sdk_guitools/sim_drone.py index fa2c519..b46b15d 100644 --- a/guiTools/spiri_sdk_guitools/sim_drone.py +++ b/guiTools/spiri_sdk_guitools/sim_drone.py @@ -131,6 +131,7 @@ class Robot: asyncio.create_task(container_logs(container, logelement)) with ui.expansion("Full details").classes("w-full outline outline-1").style("margin: 10px;"): details_widget = ui.codemirror(yaml.dump(container.attrs), language="yaml",theme="basicDark") + details_widget.enabled = False # Check for containers that have been removed removed = set(docker_elements.keys()) - set(self.containers()) for container in removed: -- 2.40.1