spiri-sdk/guiTools/spiri_sdk_guitools/launcher.py

105 lines
4.2 KiB
Python
Raw Normal View History

from nicegui import ui, binding, app
import subprocess
from collections import defaultdict
2024-11-06 12:58:14 -04:00
import docker
import time
docker_client = docker.from_env()
# Dictionary of applications: key is the button text, value is the command to execute
applications = {
2024-11-05 11:22:15 -04:00
"Terminal": ["qterminal"],
"rqt": ["rqt"],
"rviz2": ["rviz2"],
"Gazebo": ["/spawn_drones.sh"],
"Gazebo Standalone": "gz sim -v4".split(),
# Add more applications here if needed
}
# Function to launch an application
def launch_app(command):
try:
subprocess.Popen(command)
except FileNotFoundError:
print(f"{command[0]} not found. Make sure it's installed and accessible in the PATH.")
# Create the NiceGUI interface
2024-11-05 11:22:15 -04:00
ui.label("Spiri Robotics SDK").style('font-size: 40px; margin-bottom: 10px;').classes('w-full text-center')
2024-09-19 14:33:29 -03:00
robots = []
from spiri_sdk_guitools.sim_drone import Robot
2024-11-06 12:58:14 -04:00
@ui.refreshable
def show_robots():
with ui.element().classes('w-full'):
for robot in robots:
@ui.refreshable
def container_status(robot):
ui.label("Containers")
for container in robot.containers():
ui.label(f"{container.name} {container.status}")
with ui.card().style('margin: 10px;').classes('w-full'):
ui.label(f"{robot.robot_type}")
ui.label(f"""Sysid: {robot.sysid}""")
ui.button("Start", on_click=robot.start)
ui.button("Stop", on_click=robot.stop)
def delete_robot():
robot.stop()
robots.remove(robot)
show_robots.refresh()
ui.button("Delete", on_click=delete_robot)
with ui.expansion("Details").style('margin: 10px;').classes('w-full'):
container_status(robot)
ui.timer(1, container_status.refresh)
logwidget = ui.expansion("Logs").style('margin: 10px;').classes('w-full')
@ui.page('/')
def main():
with ui.tabs().classes('w-full') as tabs:
tab_tools = ui.tab('Tools')
tab_robots = ui.tab('Robots')
# two = ui.tab('Two')
2024-11-06 12:58:14 -04:00
with ui.tab_panels(tabs, value=tab_tools).classes("w-full"):
with ui.tab_panel(tab_tools):
# Create and place buttons dynamically based on the dictionary
with ui.grid(columns=3):
for app_name, command in applications.items():
ui.button(app_name, on_click=lambda cmd=command: launch_app(cmd)).style('width: 150px; height: 50px; margin: 5px;')
with ui.tab_panel(tab_robots):
2024-11-06 12:58:14 -04:00
#Add a new robot
with ui.element():
ui.label("Add new robot")
newRobotParams = defaultdict(binding.BindableProperty)
2024-11-06 12:58:14 -04:00
ui.number(value=1, label="SysID", min=1, max=254,
).bind_value(newRobotParams, 'sysid')
ui.textarea(value="./sdk/docker-compose.yml", label="Compose files (comma or newline seperated)").bind_value(newRobotParams, 'compose_files')
def new_robot():
robot = Robot(**newRobotParams)
2024-11-06 12:58:14 -04:00
# robot.start()
robots.append(robot)
2024-11-06 12:58:14 -04:00
newRobotParams['sysid'] += 1
show_robots.refresh()
ui.button("Add", on_click=new_robot)
2024-11-06 12:58:14 -04:00
with ui.element():
ui.label("Debug")
def cleanup_all_containers():
#Find all containers that start with spiri-sdk
containers = docker_client.containers.list(all=True)
removal_count = 0
for container in containers:
if container.name.startswith("robot-sim-"):
container.remove(force=True)
removal_count += 1
ui.label(f"Removed {removal_count} containers")
ui.button("Cleanup all containers", on_click=cleanup_all_containers)
ui.separator()
ui.label("Current robots")
robotwidget = show_robots()
# Start the NiceGUI application
ui.run(title="Spiri SDK Launcher", port=8923, dark=None)