feature/multiple-compose #11
|
@ -70,7 +70,7 @@ async def main():
|
||||||
).bind_value(newRobotParams, 'sysid')
|
).bind_value(newRobotParams, 'sysid')
|
||||||
default_robot_compose = (
|
default_robot_compose = (
|
||||||
"/robots/spiri-mu/core/docker-compose.yaml\n"
|
"/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.label("Compose files").classes("text-xl")
|
||||||
ui.codemirror(value=default_robot_compose, language="bash", theme="basicDark").bind_value(newRobotParams, 'compose_files')
|
ui.codemirror(value=default_robot_compose, language="bash", theme="basicDark").bind_value(newRobotParams, 'compose_files')
|
||||||
|
|
|
@ -6,6 +6,7 @@ import os
|
||||||
import sh
|
import sh
|
||||||
import subprocess
|
import subprocess
|
||||||
from nicegui import ui, run, app
|
from nicegui import ui, run, app
|
||||||
|
import yaml
|
||||||
|
|
||||||
import docker
|
import docker
|
||||||
import aiodocker
|
import aiodocker
|
||||||
|
@ -96,6 +97,7 @@ class Robot:
|
||||||
container_status = {}
|
container_status = {}
|
||||||
with element:
|
with element:
|
||||||
while True:
|
while True:
|
||||||
|
with logger.catch():
|
||||||
# Poll for data that changes
|
# Poll for data that changes
|
||||||
for container in self.containers():
|
for container in self.containers():
|
||||||
try:
|
try:
|
||||||
|
@ -110,18 +112,26 @@ class Robot:
|
||||||
docker_elements[container] = ui.element().classes("w-full")
|
docker_elements[container] = ui.element().classes("w-full")
|
||||||
with docker_elements[container]:
|
with docker_elements[container]:
|
||||||
ui.label().bind_text(container_status, container).classes(
|
ui.label().bind_text(container_status, container).classes(
|
||||||
"text-lg"
|
"text-2xl"
|
||||||
)
|
)
|
||||||
#Show the command the container is running
|
#Show the command the container is running
|
||||||
# ui.label(container.attrs["Config"]["Cmd"])
|
# 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 = ui.codemirror(" ".join(container.attrs["Config"]["Cmd"]), language="bash",theme="basicDark").classes('h-auto max-h-32')
|
||||||
cmd_widget.enabled = False
|
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 = (
|
logelement = (
|
||||||
ui.expansion("Logs")
|
ui.expansion("Logs")
|
||||||
.style("margin: 10px;")
|
.style("margin: 10px;")
|
||||||
.classes("w-full outline outline-1")
|
.classes("w-full outline outline-1")
|
||||||
)
|
)
|
||||||
asyncio.create_task(container_logs(container, logelement))
|
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
|
# Check for containers that have been removed
|
||||||
removed = set(docker_elements.keys()) - set(self.containers())
|
removed = set(docker_elements.keys()) - set(self.containers())
|
||||||
for container in removed:
|
for container in removed:
|
||||||
|
@ -138,7 +148,7 @@ class Robot:
|
||||||
scroll_area.clear()
|
scroll_area.clear()
|
||||||
#Filter for topics that start with self.robot_name
|
#Filter for topics that start with self.robot_name
|
||||||
for topic in node_dummy.get_topic_names_and_types():
|
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])
|
ui.label(topic[0])
|
||||||
await asyncio.sleep(10)
|
await asyncio.sleep(10)
|
||||||
|
|
||||||
|
@ -221,6 +231,11 @@ class Robot:
|
||||||
self.spawn_gz_model()
|
self.spawn_gz_model()
|
||||||
logger.info("Starting drone stack, this may take some time")
|
logger.info("Starting drone stack, this may take some time")
|
||||||
for compose_file in self.compose_files:
|
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):
|
if not isinstance(compose_file, Path):
|
||||||
compose_file = Path(compose_file)
|
compose_file = Path(compose_file)
|
||||||
if not compose_file.exists():
|
if not compose_file.exists():
|
||||||
|
@ -236,15 +251,17 @@ class Robot:
|
||||||
"-f",
|
"-f",
|
||||||
compose_file.as_posix(),
|
compose_file.as_posix(),
|
||||||
"up",
|
"up",
|
||||||
|
*arguments,
|
||||||
]
|
]
|
||||||
command = " ".join(args)
|
command = " ".join(args)
|
||||||
|
|
||||||
logger.info(f"Starting drone stack with command: {command}")
|
logger.info(f"Starting drone stack with command: {command}")
|
||||||
docker_stack = subprocess.Popen(
|
docker_stack = subprocess.Popen(
|
||||||
args,
|
args,
|
||||||
stdout=subprocess.PIPE,
|
# stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE,
|
# stderr=subprocess.PIPE,
|
||||||
)
|
)
|
||||||
|
logger.info(f"Started drone stack with PID: {docker_stack.pid}")
|
||||||
|
|
||||||
@logger.catch
|
@logger.catch
|
||||||
def spawn_gz_model(self):
|
def spawn_gz_model(self):
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
FROM git.spirirobotics.com/spiri/services-ros2-mavros:main
|
FROM git.spirirobotics.com/spiri/services-ros2-mavros:main
|
||||||
|
|
||||||
RUN apt-get update
|
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
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,10 @@ services:
|
||||||
ipc: host
|
ipc: host
|
||||||
network_mode: host
|
network_mode: host
|
||||||
# image: git.spirirobotics.com/spiri/services-ros2-mavros:main
|
# image: git.spirirobotics.com/spiri/services-ros2-mavros:main
|
||||||
|
#Build the iamge, give it a name, don't try to pull the image
|
||||||
build: ./
|
build: ./
|
||||||
|
image: spirisdk-virtual_camera
|
||||||
|
pull_policy: never
|
||||||
environment:
|
environment:
|
||||||
- RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
|
- 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
|
command: ros2 run ros_gz_image image_bridge /world/${WORLD_NAME}/model/${ROBOT_NAME}/link/pitch_link/sensor/camera/image
|
Loading…
Reference in New Issue