background
previously, we had done ADS ros package directly talk with lgsvl. the step further is to trigger ADS ros nodes from scenario python script
a few requirements:
for ADS ros should be integrated with each scenario python script, which means, when the python script finished, the ADS ros should exit
the ads ros package shell script is independ of python script
execute shell in Python
- to call a shell command directly with
os.system(cmd)
or
|
|
- to run shell script with a python subprocess
|
|
subprocess.Popen()
return the process object
a few helpful commands to debug rosrun:
|
|
ros1 to python3
there is an real issue, due to the ADS ros package is mostly implemented by ROS1, maintained by the algorithm team. but lgsvl scenario is running with python3. ROS1 matches Python2. so there comes the solution, either to upgrade the ADS ros pakcage to ROS2, or find a way to run ROS1 in python3 env.
conda base env
we had decided to adapt ROS1 in python3 env. as the host machine has conda env, first need to disable conda base.
|
|
as lgsvl scenario is runned with conda python3 env, inside which used subprocess
to run ADS ros shell, in which creates a few new gnome-terminal
s, which are non log-in terminal, and the trick things here: even though disabled auto activate base, and the terminal has no header (base)
, but when check the python path, it still points to the conda/bin/python
, which will fail rosbridge_launch.server
, which is a pure ros1 and python2 module.
so need check if conda --version
in the ads ros shell script is in current terminal, if does, run conda deactivate
, which gives error:
|
|
it looks there is some mess up, with init conda.sh
is in ~/.bashrc
, but during the new terminal ceated, it doens’t confgiure all right. which can be fixed :
|
|
in this way, we run lgsvl scenario in python3, as well as can new with python2 terminals to run ads ros nodes from this python3 terminal
ros scripts path is not python path
as we try to separate python scripts from ads ros nodes, so need some global env variable for the ros scripts path.
kill all ros nodes gracefully
we need restart/shutdown the ads ros nodes package at each time when python scenario script start/stop, which has two steps:
to shutdown ros nodes, e.g. rosnode kill
to close all the gnome-terminals to run the ros nodes
the second step is very tricky, need some understand. A terminal is a file. Like /dev/tty. Files do not have a process id. The process that “owns” the terminal is usually called the controlling process, or more correctly, the process group leader. gnome-terminal
runs a single pid, it creates a child process for each and every window and/or tab. and can retrieve these child processes by the command:
$ pgrep -P <pid_of_gnome-terminal>
Many terminals seem to mask themselves as xterm-compatible, which is reported by echo $TERM or echo $COLORTERM.
|
|
#! /bin/bash
gnome_pid=`pgrep gnome-terminal`
subpids=`pgrep -P ${gnome_pid}`
if [ ! $1 ]; then
echo "missing the gnome-terminal pid, exit"
exit -1
fi
#shutdown the ros nodes
rosnode kill -a > /dev/null 2>&1
killall -9 rosmaster > /dev/null 2>&1
#shutdown the terminals where ros nodes hosted
for pid in $subpids
do
if [[ $pid != $1 ]] ; then
echo $pid
kill $pid
fi
done
tips: the implement has a litle problem when integrate with lgsvl when the simulation time is short, e.g. 1sec, then ros_clear.sh
can’t catch the opened gnome-terminals from ros_start.sh
.
find the process name using PID
$ ps aux | grep PID
$ ps -p PID -o format
$ curpid=`ps -p $$ -o ppid=`
the output of ps aux
- –> in the foreground process group
s –> is a session leader
summary
so far, we integrated ads ros packages into python, which then talk to lgsvl.