Initial webpage and backend

This commit is contained in:
2026-03-17 12:33:12 +01:00
parent 9010bac9a0
commit 28b120b88e
39 changed files with 153532 additions and 4 deletions

16
toid_cli/package.xml Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>toid_cli</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="82343504+pimpest@users.noreply.github.com">petar</maintainer>
<license>MIT</license>
<depend>python3-fastapi</depend>
<depend>python3-pydantic</depend>
<export>
<build_type>ament_python</build_type>
</export>
</package>

View File

4
toid_cli/setup.cfg.old Normal file
View File

@@ -0,0 +1,4 @@
[develop]
script_dir=$base/lib/toid_cli
[install]
install_scripts=$base/lib/toid_cli

25
toid_cli/setup.py Normal file
View File

@@ -0,0 +1,25 @@
from setuptools import find_packages, setup
package_name = 'toid_cli'
setup(
name=package_name,
version='0.0.0',
packages=find_packages(exclude=['test']),
data_files=[
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='pimpest',
maintainer_email='82343504+pimpest@users.noreply.github.com',
description='TODO: Package description',
license='MIT',
entry_points={
'console_scripts': [
'toid_cli = toid_cli.main:main'
],
},
)

View File

108
toid_cli/toid_cli/main.py Normal file
View File

@@ -0,0 +1,108 @@
import subprocess
import uuid
import os
import signal
from fastapi import FastAPI
from pydantic import BaseModel
import uvicorn
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=[
"*"
],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# store running launch processes
launch_processes = {}
class LaunchRequest(BaseModel):
package: str
launch_file: str
args: dict = {}
@app.post("/launch/start")
def start_launch(req: LaunchRequest):
launch_id = str(uuid.uuid4())
cmd = ["ros2", "launch", req.package, req.launch_file]
for k, v in req.args.items():
cmd.append(f"{k}:={v}")
log_dir = "log"
os.makedirs(log_dir, exist_ok=True)
stdout_file = open(f"{log_dir}/{launch_id}_stdout.log", "w")
stderr_file = open(f"{log_dir}/{launch_id}_stderr.log", "w")
proc = subprocess.Popen(
cmd,
stdout=stdout_file,
stderr=stderr_file,
preexec_fn=os.setsid
)
launch_processes[launch_id] = proc
return {
"launch_id": launch_id,
"pid": proc.pid,
"command": " ".join(cmd)
}
@app.get("/launch/list")
def list_launches():
running = {}
for lid, proc in launch_processes.items():
running[lid] = {
"pid": proc.pid,
"running": proc.poll() is None
}
return running
@app.post("/launch/stop/{launch_id}")
def stop_launch(launch_id: str):
if launch_id not in launch_processes:
return {"error": "launch id not found"}
proc = launch_processes[launch_id]
if proc.poll() is None:
os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
return {"stopped": launch_id}
@app.post("/launch/stop_all")
def stop_all():
for proc in launch_processes.values():
if proc.poll() is None:
os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
return {"status": "all stopped"}
def main():
uvicorn.run(
"toid_cli.main:app",
host="0.0.0.0",
port=8000,
reload=False
)
if __name__ == "__main__":
main()