Skip to content

Commit

Permalink
support multiple robots end to end in simulation
Browse files Browse the repository at this point in the history
  • Loading branch information
merlinran committed Jan 4, 2022
1 parent 0ed57e7 commit 13ba410
Show file tree
Hide file tree
Showing 12 changed files with 52 additions and 44 deletions.
29 changes: 20 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,29 +1,40 @@
LOCAL_IMAGE = acorn_docker:1.0
REMOTE_IMAGE = merlinran/acorn_docker
ACORN_NAMES ?= simulation-1

.PHONY: list
list:
@echo "Welcome! You may want to try one of the following:\n---"; \
grep "^.PHONY:" Makefile | grep "#" | cut -d ":" -f 2- | sed "s/\w*#/\t#/g" | sed "s/^/make/"

.PHONY: simulation # Run the vehicle and server containers in simulation mode.
.PHONY: simulation # Run the vehicle and server containers in simulation mode. Use envvar ACORN_NAMES to set the name of each simulated vehicle.
simulation: docker-image
@DOCKER_COMPOSE_FILE=docker-compose-simulation.yml make restart-docker-compose &&\
@docker-compose -f docker-compose-server.yml up -d && \
export server_ip=`docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' acorn_server`; \
for name in $(ACORN_NAMES); do \
NAME=$${name} SERVER_IP=$${server_ip} envsubst < docker-compose-simulation.yml | COMPOSE_IGNORE_ORPHANS=true docker-compose --file /dev/stdin --project-directory . up -d; \
done &&\
echo "Please visit http://localhost"

.PHONY: attach-vehicle # Attach to the shell of the vehicle container. It creates the container if it doesn't exist.
.PHONY: attach-vehicle # Attach to the shell of the first vehicle container. It creates the container if it doesn't exist.
attach-vehicle:
@test -z `docker ps -f "name=acorn_vehicle" -q` && make docker-vehicle; \
docker exec -it acorn_vehicle /bin/sh
@first_container=`docker ps --filter "name=acorn_*" -q | head -1`; \
if [[ -z "$${first_container}" ]]; then \
make docker-vehicle; \
fi; \
docker exec -it $${first_container} /bin/sh

.PHONY: attach-server # Attach to the shell of the server container. It creates the container if it doesn't exist.
attach-server:
@test -z `docker ps -f "name=acorn_server" -q` && make docker-server; \
docker exec -it acorn_server /bin/sh

.PHONY: stop # Stop both the vehicle and server containers.
.PHONY: stop # Stop all the vehicle and server containers.
stop:
@docker-compose -f docker-compose-simulation.yml down --remove-orphans
@containers=`docker ps --filter "name=acorn_*" -q`; \
if [[ -n "$${containers}" ]]; then \
docker stop $${containers} && docker rm $${containers}; \
fi \

.PHONY: docker-test # Start the vehicle container in test mode and run the tests in it.
docker-test: docker-image
Expand Down Expand Up @@ -52,8 +63,8 @@ docker-server: docker-image

.PHONY: restart-docker-compose
restart-docker-compose:
@docker-compose -f $${DOCKER_COMPOSE_FILE} down --remove-orphans; \
docker-compose -f $${DOCKER_COMPOSE_FILE} up -d
@docker-compose -f $${DOCKER_COMPOSE_FILE} down --remove-orphans
@COMPOSE_IGNORE_ORPHANS=true docker-compose -f $${DOCKER_COMPOSE_FILE} up -d

.PHONY: docker-image
docker-image: Dockerfile
Expand Down
10 changes: 5 additions & 5 deletions docker-compose-simulation.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
version: "3.7"

services:
acorn_vehicle:
acorn_vehicle_${NAME}:
extends:
file: docker-compose-vehicle.yml
service: acorn_vehicle
container_name: acorn_vehicle_${NAME}
environment:
VEHICLE_NAME: ${NAME}
volumes:
- .:/home/pi/
- ./.bashrc:/home/pi/.bashrc
command: sh -c /home/pi/vehicle/autolaunch_vehicle_sim.sh
network_mode: "bridge"
ipc: host
acorn_server:
extends:
file: docker-compose-server.yml
service: acorn_server
10 changes: 4 additions & 6 deletions docker-compose-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ version: "3.7"
services:
acorn_vehicle_test:
extends:
file: docker-compose-simulation.yml
file: docker-compose-vehicle.yml
service: acorn_vehicle
volumes:
- .:/home/pi/
- ./.bashrc:/home/pi/.bashrc
command: sleep infinity
# acorn_server:
# extends:
# file: docker-compose-simulation.yml
# service: acorn_server
# command: sleep infinity
2 changes: 1 addition & 1 deletion server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def map_test():

def date_handler(obj):
if isinstance(obj, (datetime.datetime, datetime.date)):
return obj.isoformat() + "-07:00"
return obj.isoformat() + "+00:00"
else:
return None

Expand Down
7 changes: 6 additions & 1 deletion server/zmq_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,12 @@ def handle_command(r, command, key, msg):
command_key = redis_utils.get_robot_command_key(key)
# if not command_key:
# print("Error. Command key is none. Key was:")
command_object = pickle.loads(r.get(command_key))
raw = r.get(command_key)
if not raw:
print("Robot {} is not found. Assuming a new one".format(command_key))
command_object = RobotCommand()
else:
command_object = pickle.loads(raw)

# If the object changed definition we need to create a new one.
if len(dir(RobotCommand())) != len(dir(command_object)):
Expand Down
2 changes: 2 additions & 0 deletions vehicle/autolaunch_vehicle_sim.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ echo $PWD
echo Sleep 5...
sleep 5
echo Start Sessions...
gateway_ip=`ip route show 0.0.0.0/0 | cut -d\ -f3`
export SERVER_IP=${gateway_ip}
tmux new-session -d -s "main" sh /home/pi/vehicle/start_main.sh --sim &
tmux new-session -d -s "motors" sh /home/pi/vehicle/start_motors.sh --simulated_hardware &
echo Started. Begin infinite loop.
Expand Down
18 changes: 8 additions & 10 deletions vehicle/master_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,9 @@ def __init__(self, simulation, debug):
self.logger = logging.getLogger('main')
config_logging(self.logger, self.debug)

def setup(self, config):
def setup(self, name, server, site):
# Initialize robot object.
name = str(config["vehicle_name"])
server = str(config["server"])
if ":" not in server:
server += ":5570" # back compatibility to old server config files.
site = str(config["site"])
self.logger.info("Using server from yaml {}".format(server))
self.logger.info("Using server {}".format(server))
self.acorn = model.Robot(self.simulation, self.logger)
self.acorn.setup(name, server, site)

Expand Down Expand Up @@ -193,15 +188,15 @@ def run(self, stop_signal):

updated_object |= self.update_from_remote_control(gps_count, remote_to_main_lock, remote_to_main_string)
# print("6666")
seconds_since_update = (datetime.now() - self.acorn.time_stamp).total_seconds()
seconds_since_update = (datetime.utcnow() - self.acorn.time_stamp).total_seconds()

if self.simulation:
period = _SIMULATION_UPDATE_PERIOD
else:
period = _UPDATE_PERIOD

if updated_object and seconds_since_update > period:
self.acorn.time_stamp = datetime.now()
self.acorn.time_stamp = datetime.utcnow()
try:
self.server_comms_parent_conn.send([_CMD_UPDATE_ROBOT, self.acorn.key, pickle.dumps(self.acorn)])
self.acorn.energy_segment_list = []
Expand Down Expand Up @@ -407,7 +402,10 @@ def run_main(simulation, debug):
else:
yaml_path = _YAML_NAME_RASPBERRY
config = load_yaml_config(yaml_path)
main_process.setup(config)
name = os.getenv('VEHICLE_NAME', config.get('vehicle_name', 'noname'))
server = os.getenv('SERVER_IP', config.get('server', '127.0.0.1'))

main_process.setup(name, "{}:5570".format(server), config.get('site', 'nosite'))
stop_signal = mp.Event()
try:
main_process.run(stop_signal)
Expand Down
2 changes: 1 addition & 1 deletion vehicle/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def __init__(self, simulated_data=False, logger=None):
self.record_gps_command = GPS_RECORDING_CLEAR
self.activate_autonomy = False
self.autonomy_velocity = 0
self.time_stamp = datetime.now()
self.time_stamp = datetime.utcnow()
self.debug_points = None
self.wifi_strength = None
self.wifi_ap_name = None
Expand Down
4 changes: 2 additions & 2 deletions vehicle/remote_control_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -1026,8 +1026,8 @@ def write_errors(self, error_messages):
with open("error_log.txt", 'a+') as file1:
file1.write("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n")
file1.write("Disegagement Log\r\n")
file1.write(datetime.datetime.now().strftime(
"%a %b %d, %I:%M:%S %p\r\n"))
file1.write(datetime.datetime.utcnow().strftime(
"%a %b %d, %I:%M:%S %p+00:00\r\n"))
file1.write("Last Wifi signal strength: {} dbm\r\n".format(
self.robot_object.wifi_strength))
file1.write("Last Wifi AP associated: {}\r\n".format(
Expand Down
2 changes: 1 addition & 1 deletion vehicle/server_config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
vehicle_name: acorn1
#server: 192.168.1.152
server: 192.168.1.170:5570
server: 192.168.1.170
#server: 192.168.86.69
site: twistedfields
3 changes: 1 addition & 2 deletions vehicle/server_config_sim.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
vehicle_name: acorn1
server: 127.0.0.1:5570
server: 127.0.0.1
site: twistedfields
7 changes: 1 addition & 6 deletions vehicle/tests/test_main_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,11 @@ def mock_motors():
obj = pickle.loads(motors_socket.recv_pyobj())
assert obj is not None, "should have sent the commands to motor"

cfg = """
vehicle_name: acorn1
server: 127.0.0.1:{}
site: twistedfields
""".format(server_port)
server_thread = threading.Thread(target=mock_server, daemon=True)
server_thread.start()

main_process = MainProcess(simulation=True, debug=True)
main_process.setup(yaml.safe_load(cfg))
main_process.setup("test", "127.0.0.1:{}".format(server_port), "test-site")
stop_signal = mp.Event()
main_thread = threading.Thread(target=lambda: main_process.run(stop_signal), daemon=True)
main_thread.start()
Expand Down

0 comments on commit 13ba410

Please sign in to comment.