@@ -28,16 +28,41 @@ def get_running_containers(client: docker.DockerClient) -> Dict[str, Container]:
28
28
containers = client .containers .list (filters = {"name" : "phyto-arm-" })
29
29
return {c .name .replace ('phyto-arm-' , '' ): c for c in containers }
30
30
31
+ # This is here to wire up arguments to volume mounts to ROS launch parameters.
32
+ # The alternative is to generate a mount automatically and pass the paths as
33
+ # arguments to their respective launch files.
34
+ def handle_special_volumes_by_process (process_name : str , process_config : dict ) -> dict :
35
+ volumes = {}
36
+ if process_name == "main" :
37
+ volumes [process_config ['launch_args' ]['rosbag_dir' ]] = {
38
+ "bind" : "/app/volumes/rosbags" , # Must match launch file
39
+ "mode" : "rw"
40
+ }
41
+ if process_name == "arm_ifcb" :
42
+ volumes [process_config ['launch_args' ]['routines_dir' ]] = {
43
+ "bind" : "/app/volumes/routines" , # Must match launch file
44
+ "mode" : "ro"
45
+ }
46
+ volumes [process_config ['launch_args' ]['data_dir' ]] = {
47
+ "bind" : "/app/volumes/ifcbdata" , # Must match launch file
48
+ "mode" : "rw"
49
+ }
50
+ return volumes
51
+
31
52
def start_container (
32
53
client : docker .DockerClient ,
33
54
network : docker .models .networks .Network ,
34
55
config_path : Path ,
35
56
process_name : str ,
36
- process_config : dict ,
37
- image_name : str
57
+ config : dict
38
58
) -> Container :
39
59
"""Start a single PhytO-ARM container"""
60
+
61
+ process_config = config ['processes' ][process_name ]
62
+ image_name = config ['docker_image' ]
40
63
container_name = f"phyto-arm-{ process_name } "
64
+ log_dir = config ['log_dir' ]
65
+ log_mount = "/app/volumes/roslogs"
41
66
42
67
# Base volumes that all containers need
43
68
volumes = {
@@ -48,16 +73,16 @@ def start_container(
48
73
str (config_path .parent .absolute ()): {
49
74
"bind" : "/app/configs" ,
50
75
"mode" : "ro"
76
+ },
77
+ log_dir : {
78
+ "bind" : log_mount ,
79
+ "mode" : "rw"
51
80
}
52
81
}
53
82
54
83
# Add process-specific volumes
55
- for vol_name , host_path in process_config .get ('volumes' , {}).items ():
56
- Path (host_path ).mkdir (parents = True , exist_ok = True )
57
- volumes [host_path ] = {
58
- "bind" : f"/app/volumes/{ vol_name } " ,
59
- "mode" : "rw"
60
- }
84
+ special_volumes = handle_special_volumes_by_process (process_name , process_config )
85
+ volumes .update (special_volumes )
61
86
62
87
# Handle devices
63
88
devices = [
@@ -85,7 +110,8 @@ def start_container(
85
110
"ports" : ports ,
86
111
"environment" : {
87
112
"DONT_SCREEN" : "1" , # screen is not needed within containers
88
- "ROS_MASTER_URI" : "http://phyto-arm-main:11311"
113
+ "ROS_MASTER_URI" : "http://phyto-arm-main:11311" ,
114
+ "ROS_LOG_DIR" : log_mount
89
115
}
90
116
}
91
117
@@ -143,8 +169,7 @@ def start_processes(config_path: Path, process_names: Optional[list[str]] = None
143
169
# Always start main first if it's in the list
144
170
if 'main' in processes :
145
171
start_container (
146
- client , network , config_path , 'main' ,
147
- processes ['main' ], config ['docker_image' ]
172
+ client , network , config_path , 'main' , config
148
173
)
149
174
150
175
# Wait for ROS master to start
@@ -157,8 +182,7 @@ def start_processes(config_path: Path, process_names: Optional[list[str]] = None
157
182
for name , process_config in processes .items ():
158
183
if process_config .get ('enabled' , True ):
159
184
start_container (
160
- client , network , config_path , name ,
161
- process_config , config ['docker_image' ]
185
+ client , network , config_path , name , config
162
186
)
163
187
164
188
# If process is not enabled in the config, but was requested, print a warning
0 commit comments