Skip to content

Commit

Permalink
improve docker and simulation control
Browse files Browse the repository at this point in the history
  • Loading branch information
rbonghi committed Jan 23, 2025
1 parent a899e7c commit 8c76687
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 26 deletions.
74 changes: 54 additions & 20 deletions src/nanosaur/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# https://gabrieldemarmiesse.github.io/python-on-whales/
from python_on_whales import docker, DockerClient
from nanosaur.utilities import Params, RobotList, Robot, get_nanosaur_raw_github_url, get_nanosaur_home
from python_on_whales import docker, DockerClient, DockerException
from nanosaur.utilities import Params, RobotList, get_nanosaur_raw_github_url, get_nanosaur_home, build_env_file, is_env_file
from nanosaur.prompt_colors import TerminalFormatter
import os
import requests
Expand Down Expand Up @@ -66,20 +66,6 @@ def create_simple(platform, params: Params, args) -> bool:
return True


def build_env_file(params, env_path, robot: Robot):
uid = os.getuid()
gid = os.getgid()
# Create a .env file and save UID and GID
with open(env_path, 'w') as env_file:
env_file.write(f"USER_UID={uid}\n")
env_file.write(f"USER_GID={gid}\n")
# Check which simulation tool is selected and save it in the .env file
simulation_tool = params['simulation_tool'].lower().replace(' ', '_')
env_file.write(f"SIMULATION={simulation_tool}\n")
# Pass robot ros commands
env_file.write(f"COMMANDS={robot.config_to_ros()}\n")


def docker_start(platform, params: Params, args):
"""Start the docker container."""

Expand All @@ -92,19 +78,67 @@ def docker_start(platform, params: Params, args):
nanosaur_home_path = get_nanosaur_home()
# Create the full file path
docker_compose_path = os.path.join(nanosaur_home_path, docker_compose)
env_path = os.path.join(nanosaur_home_path, '.env')

robot = RobotList.get_robot(params)

# Check which simulation tool is selected only if robot.simulation is true
if robot.simulation and 'simulation_tool' not in params:
print(TerminalFormatter.color_text("No simulation tool selected. Please run simulation set first.", color='red'))
return False

# Build env file
build_env_file(params, env_path, robot)
if not is_env_file():
print(TerminalFormatter.color_text("Creating the environment file...", color='green'))
build_env_file(params)
print(TerminalFormatter.color_text(f"robot {robot.name} starting", color='green'))
# Create a DockerClient object with the docker-compose file
nanosaur_compose = DockerClient(compose_files=[docker_compose_path])
if args.build:
print(TerminalFormatter.color_text("Building the Docker container...", color='green'))
nanosaur_compose.compose.build()
# Start the container in detached mode
nanosaur_compose.compose.up(detach=args.detach)
try:
nanosaur_compose.compose.up(detach=args.detach)
except DockerException as e:
print(TerminalFormatter.color_text(f"Error starting the robot: {e}", color='red'))
return False


def docker_simulator_start(platform, params: Params, args):
"""Start the simulation tools."""

if not docker.compose.is_installed():
print(TerminalFormatter.color_text("Please install Docker and Docker Compose before running the simulation.", color='red'))
return False

workspace_type = "robot" if platform['Machine'] == 'jetson' else "simulation"
docker_compose = f"docker-compose.{workspace_type}.yml"
nanosaur_home_path = get_nanosaur_home()
# Create the full file path
docker_compose_path = os.path.join(nanosaur_home_path, docker_compose)
robot = RobotList.get_robot(params)

# Check which simulation tool is selected
if 'simulation_tool' not in params:
print(TerminalFormatter.color_text("No simulation tool selected. Please run simulation set first.", color='red'))
return False

# Create a DockerClient object with the docker-compose file
nanosaur_compose = DockerClient(compose_files=[docker_compose_path])
if len(nanosaur_compose.compose.ps()) > 0:
print(TerminalFormatter.color_text(f"The robot {robot.name} is already running.", color='red'))
return False
# Build env file
if not is_env_file():
print(TerminalFormatter.color_text("Creating the environment file...", color='green'))
build_env_file(params)
print(TerminalFormatter.color_text(f"robot {robot.name} starting", color='green'))
# Start the container in detached mode
simulation_tool = params['simulation_tool'].lower().replace(' ', '_')
try:
nanosaur_compose.compose.up(services=[f'nanosaur_{simulation_tool}'])
except DockerException as e:
print(TerminalFormatter.color_text(f"Error starting the simulation tool: {e}", color='red'))
return False


def docker_stop(platform, params: Params, args):
Expand Down
16 changes: 13 additions & 3 deletions src/nanosaur/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@
import argparse
import subprocess
from nanosaur import workspace
from nanosaur.docker import docker_simulator_start
from nanosaur.prompt_colors import TerminalFormatter
from nanosaur.utilities import Params, RobotList
from nanosaur.utilities import Params, RobotList, build_env_file, is_env_file


# Dictionary of simulation tools and their commands
Expand Down Expand Up @@ -57,6 +58,8 @@ def parser_simulation_menu(subparsers: argparse._SubParsersAction, params: Param
# Add simulation start subcommand
parser_simulation_start = simulation_subparsers.add_parser(
'start', help="Start the selected simulation")
parser_simulation_start.add_argument(
'--debug', action='store_true', help="Start the simulation in debug mode")
parser_simulation_start.set_defaults(func=simulation_start)

# Add simulation set subcommand
Expand All @@ -66,7 +69,7 @@ def parser_simulation_menu(subparsers: argparse._SubParsersAction, params: Param
return parser_simulation


def start_robot_simulation(params):
def simulation_robot_start_debug(params):
nanosaur_ws_path = workspace.get_workspace_path(params, 'ws_simulation_name')
bash_file = f'{nanosaur_ws_path}/install/setup.bash'
# Check which simulation tool is selected
Expand Down Expand Up @@ -112,7 +115,7 @@ def start_robot_simulation(params):
return False


def simulation_start(platform, params: Params, args):
def simulation_start_debug(platform, params: Params, args):
"""Install the simulation tools."""
nanosaur_ws_path = workspace.get_workspace_path(params, 'ws_simulation_name')
bash_file = f'{nanosaur_ws_path}/install/setup.bash'
Expand Down Expand Up @@ -157,6 +160,13 @@ def simulation_start(platform, params: Params, args):
return False


def simulation_start(platform, params: Params, args):
if args.debug:
return simulation_start_debug(platform, params, args)
else:
return docker_simulator_start(platform, params, args)


def simulation_set(platform, params: Params, args):
"""Set the simulation tools."""

Expand Down
26 changes: 25 additions & 1 deletion src/nanosaur/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,28 @@ def print_all_robots(self, robot_idx=None):
print(f" {TerminalFormatter.color_text(f'Robot {idx}:', bold=True)} {robot}")


def is_env_file():
nanosaur_home_path = get_nanosaur_home()
env_path = os.path.join(nanosaur_home_path, '.env')
return os.path.exists(env_path)

def build_env_file(params):
nanosaur_home_path = get_nanosaur_home()
env_path = os.path.join(nanosaur_home_path, '.env')
# Get current robot running
robot = RobotList.get_robot(params)
uid = os.getuid()
gid = os.getgid()
# Create a .env file and save UID and GID
with open(env_path, 'w') as env_file:
env_file.write(f"USER_UID={uid}\n")
env_file.write(f"USER_GID={gid}\n")
# Check which simulation tool is selected and save it in the .env file
simulation_tool = params['simulation_tool'].lower().replace(' ', '_')
env_file.write(f"SIMULATION={simulation_tool}\n")
# Pass robot ros commands
env_file.write(f"COMMANDS={robot.config_to_ros()}\n")

class Params:

@classmethod
Expand Down Expand Up @@ -272,9 +294,11 @@ def save(self):
# Get the current nanosaur's home directory
create_nanosaur_home()
# Save the parameters to the file
print(TerminalFormatter.color_text(f"Saving parameters to {params_file}", color='yellow'))
print(TerminalFormatter.color_text(f"Saving parameters to {params_file} and update .env file", color='yellow'))
with open(params_file, 'w') as file:
yaml.dump(self._params_dict, file)
# Make a env file
build_env_file(self._params_dict)

@staticmethod
def get_params_file() -> str:
Expand Down
4 changes: 2 additions & 2 deletions src/nanosaur/workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import argparse
from nanosaur.prompt_colors import TerminalFormatter
from nanosaur import ros
from nanosaur.simulation import start_robot_simulation
from nanosaur.simulation import simulation_robot_start_debug
from nanosaur.utilities import Params, get_nanosaur_raw_github_url, get_nanosaur_home, create_nanosaur_home, require_sudo_password
import inquirer

Expand Down Expand Up @@ -243,7 +243,7 @@ def debug(platform, params: Params, args):
""" Debug the workspace """
workspace_actions = {
'developer': lambda: ros.run_dev_script(params, get_workspace_path(params, 'ws_developer_name'), params.get('ws_developer_name', DEFAULT_WORKSPACE_DEVELOPER)),
'simulation': lambda: start_robot_simulation(params),
'simulation': lambda: simulation_robot_start_debug(params),
'perception': lambda: ros.run_dev_script(params, get_workspace_path(params, 'ws_perception_name'), params.get('ws_perception_name', DEFAULT_WORKSPACE_PERCEPTION))
}
workspace = get_selected_workspace(params, workspace_actions, args)
Expand Down

0 comments on commit 8c76687

Please sign in to comment.