Skip to content

Commit

Permalink
Using new yaml processes file
Browse files Browse the repository at this point in the history
  • Loading branch information
SyllogismRXS committed May 8, 2020
1 parent 9c14854 commit 84399cf
Show file tree
Hide file tree
Showing 10 changed files with 207 additions and 127 deletions.
9 changes: 6 additions & 3 deletions missions/example_template/mission.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,26 @@ mission_file:
altitude_origin: 0.0

entities:
- template: entity.template.xml
- type: uav
template: entity.template.xml
config:
id: 1
x: -10
y: 10
z: 20
heading: 270

- template: entity.template.xml
- type: uav
template: entity.template.xml
config:
id: 2
x: 10
y: 10
z: 10
heading: 0

- template: entity.template.xml
- type: uav
template: entity.template.xml
config:
id: 5
x: -10
Expand Down
206 changes: 138 additions & 68 deletions src/scrimmage_ros/EntityLaunch.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,92 @@
#!/usr/bin/env python

import os
import yaml
from jinja2 import Template

import scrimmage_ros.MultiProcessLogger as MPL
import scrimmage_ros.SimFilesGenerator as SFG
import scrimmage_ros.utils as sru

def get_name_command(process, entity_id):
name_t = Template(process['name'])
def get_name_command(process_info, entity_id):
name_t = Template(process_info['name'])
name = name_t.render(id=entity_id)

cmd_t = Template(process['command'])
cmd_t = Template(process_info['command'])
cmd = cmd_t.render(id=entity_id)

return name, cmd

def create_process(process_info, entity_id, output_dir, env, console, terminal):
# Allow user to specify a post delay for a process
try:
post_delay = process_info['post_delay']
except:
post_delay = 0

# Allow the user to append the environment with additional variables
try:
environment = process_info['environment']
except:
environment = dict()
env.update(environment)

# Allow the user to change whether to write to the console or not
try:
console = process_info['console']
except:
# Don't override console type
pass

# Allow the user to change the terminal type
try:
terminal = MPL.Terminal(process_info['terminal'])
except:
# Use the default terminal
pass

# Perform template substitution based on entity_id {{ id }}
name, command = get_name_command(process_info, entity_id)

return {
'command': command,
'env': env,
'console': console,
'terminal': terminal,
'file': output_dir + '/%s.log' % name,
'post_delay': post_delay
}

class EntityLaunch():
def __init__(self, mission_yaml_filename, output_dir, ros_package_name,
launch_filename, launch_args='team_id:=1 entity_id:={{ id }}',
entity_ids=None, terminal=MPL.Terminal.gnome,
processes_per_entity=[], clean_up_processes_per_entity=[],
clean_up_processes=[]):
def __init__(self, mission_yaml_filename, processess_yaml_file,
output_dir, entity_ids=None, entity_type=None):
self.entity_ids = entity_ids

# The list of processes to pass to MultiProcessLogger
self.processes = []
self.clean_up_processes = []

self._mpl = MPL.MultiProcessLogger()
# Get the full path to the processes yaml file (ros find substitution)
processes_yaml_file_path = sru.ros_find_path(processess_yaml_file)

env = os.environ.copy()
# Parse the processes file
with open(processes_yaml_file_path) as f:
self._processes_yaml = yaml.load(f, Loader=yaml.FullLoader)

env['HOME'] = sru.user_home()
self.parse_defaults()

# Ensures that python prints and logs are displayed to screen
env['PYTHONUNBUFFERED'] = '1'

# Append the roscore process
self.processes.append(
{ 'command': "roscore",
'env': env,
'console': True,
'file': output_dir + '/roscore.log',
'post_delay': 1.5
}
)

if entity_ids is None:
# Get processes that are run before entities
try:
processes_list = self._processes_yaml['processes']
except:
processes_list = []

# Append the processes that are run before entities
for p in processes_list:
self.processes.append(create_process(p, 0, output_dir, self.env, True, self.terminal))

# If the entity_ids is none, use scrimmage to run a simulation
if self.entity_ids is None:
# Generate the scrimmage mission file and scrimmage file
sfg = SFG.SimFilesGenerator(mission_yaml_filename, output_dir)

Expand All @@ -55,61 +96,90 @@ def __init__(self, mission_yaml_filename, output_dir, ros_package_name,
# Append the scrimmage process
self.processes.append(
{ 'command': "scrimmage %s" % sfg.mission_file_path,
'env': env,
'env': self.env,
'console': True,
'terminal': terminal,
'terminal': self.terminal,
'file': output_dir + '/scrimmage.log',
}
)

# Create a mapping of entity type to process infos
entity_type_to_processes = dict()
for entity_type_processes in self._processes_yaml['entity_processes']:
entity_type = entity_type_processes['type']
entity_type_to_processes[entity_type] = entity_type_processes

# Append the processes for each entity's roslaunch
for entity_id in self.entity_ids:
args_t = Template(launch_args)
args = args_t.render(id=entity_id)
# Get the entity type:
entity_type = sfg.entity_id_to_type(entity_id)

self.processes.append(
{ 'command': sru.ros_launch(ros_package_name, launch_filename, args),
'env': env,
'console': True,
'terminal': terminal,
'file': output_dir + '/entity%d/entity.log' % entity_id
}
)
# Get the entity processes for this type
try:
entity_processes = entity_type_to_processes[entity_type]['processes']
except:
entity_processes = []

# The user can pass in additional processes to run per entity
for process in processes_per_entity:
name, cmd = get_name_command(process, entity_id)

self.processes.append(
{ 'command': cmd,
'env': env,
'console': True,
'terminal': terminal,
'file': output_dir + '/entity%d/%s.log' % (entity_id, name)
}
)

# Append the cleanup processes that are associated with each entity
for process in clean_up_processes_per_entity:
name, cmd = get_name_command(process, entity_id)
self.clean_up_processes.append(
{
'command': cmd,
'env': env,
}
)
# Append the entity processes to the processes list
for p in entity_processes:
self.processes.append(create_process(p, entity_id, output_dir, self.env, True, self.terminal))

# Get the clean up processes for this type
try:
entity_clean_up_processes = entity_type_to_processes[entity_type]['clean_up']
except:
entity_clean_up_processes = []

# Append the clean up processes for this entity to the clean up list
for p in entity_clean_up_processes:
self.clean_up_processes.append(create_process(p, entity_id, output_dir, self.env, True, self.terminal))

# Append the cleanup processes that apply to all entities
for process in clean_up_processes:
name, cmd = get_name_command(process, 0)
self.clean_up_processes.append(
{
'command': cmd,
'env': env,
}
)
try:
clean_up_process_infos = self._processes_yaml['clean_up']
except:
clean_up_process_infos = []

try:
for p in clean_up_process_infos:
self.clean_up_processes.append(create_process(p, 0, output_dir, self.env, True, self.terminal))
except:
pass

def parse_defaults(self):
# Parse the defaults block
try:
self.terminal = MPL.Terminal(self._processes_yaml['defaults']['terminal'])
except:
self.terminal=MPL.Terminal.gnome

# Get environment variables to append to current environment
try:
environment = self._processes_yaml['defaults']['environment']
except:
environment = dict()

# Environment setup
self.env = os.environ.copy()
self.env['HOME'] = sru.user_home()

# Ensures that python prints and logs are displayed to screen
self.env['PYTHONUNBUFFERED'] = '1'

# Append user-defined environment variables
self.env.update(environment)

def print_processes(self):
print('---------- Processes ------------')
for p in self.processes:
print(p['command'])

print('---------- Clean up ------------')
for p in self.clean_up_processes:
print(p['command'])

def run(self):
mpl = MPL.MultiProcessLogger()

# Run the processes. Blocking.
self._mpl.run(self.processes, self.clean_up_processes)
mpl.run(self.processes, self.clean_up_processes)
1 change: 0 additions & 1 deletion src/scrimmage_ros/MultiProcessLogger.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,5 +148,4 @@ def run(self, process_info, clean_up_processes=[]):
if len(clean_up_processes) > 0:
print('Running cleanup processes...')
for process in clean_up_processes:
print(process['command'])
call(process['command'].split())
11 changes: 6 additions & 5 deletions src/scrimmage_ros/SimFilesGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@ def __init__(self, mission_yaml_file, output_dir):
with open(self.mission_file_path, 'w') as f:
f.write(self._mission_gen.mission)

# self.launch_file_path = os.path.join(sim_dir, 'sim.launch')
# with open(self.launch_file_path, 'w') as f:
# config = {'mission_file' : self.mission_file_path}
# f.write(scrimmage_ros.utils.generate_sim_roslaunch(config))

def entity_ids(self):
return self._mission_gen.entity_ids()

def entity_id_to_type(self, id):
return self._mission_gen.entity_id_to_type(id)

def options(self):
return self._mission_gen.options
6 changes: 4 additions & 2 deletions src/scrimmage_ros/test/templates/nav_2d_mission.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ mission_file:

# Configuration for each entity that will be injected into the mission file
entities:
- template: entity.template.xml
- type: car
template: entity.template.xml
config:
id: 1
team_id: 1
Expand All @@ -25,7 +26,8 @@ entities:
z: 0.42
heading: 0

- template: entity.template.xml
- type: car
template: entity.template.xml
config:
id: 2
team_id: 2
Expand Down
33 changes: 33 additions & 0 deletions src/scrimmage_ros/test/templates/nav_2d_processes.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
version: "1.0"

# Specify default values
defaults:
terminal: gnome
environment:
some_variable: some_value

# Processes that are run before entities are launched
processes:
- name: roscore
command: roscore
terminal: none
post_delay: 1.5

- name: map_server
command: stdbuf -oL roslaunch scrimmage_ros map_server.launch
terminal: none

# Processes that are run for each entity type
entity_processes:
- type: car
processes:
- name: 'entity{{ id }}'
command: 'stdbuf -oL roslaunch scrimmage_ros entity_nav_2d.launch team_id:=1 entity_id:={{ id }}'

# Clean up commands run for each entity
clean_up:
- name: hello
command: 'echo "Goodbye, Entity {{ id }}'

# Overall clean up commands (run once)
clean_up:
Loading

0 comments on commit 84399cf

Please sign in to comment.