0

I'm running a Python script. When the measured altitude is higher than 1 meter, I need to run this in the terminal:

cd ~
cd ~/catkin_ws_artag/src/launch
roslaunch pr2_indiv_1.launch

and when it's lower than 1 meter, I need to run this in the terminal:

cd ~
cd ~/catkin_ws_artag/src/launch
roslaunch pr2_indiv_0.launch

How can I do that? I tried something like this, but it doesn't work:

position = "low"
if marker.pose.position.z > 1 and position=="low":
    os.system("cd ~")
    os.system("cd ~/catkin_ws_artag/src/launch")
    os.system("roslaunch pr2_indiv_1.launch")
    position = "high"
    print "HIGH"
    ################################
if marker.pose.position.z < 1 and position=="high":
    os.system("cd ~")
    os.system("cd ~/catkin_ws_artag/src/launch")
    os.system("roslaunch pr2_indiv_0.launch")
    position = "low"
    print "LOW"

but it says: [pr2_indiv_0.launch] is not a launch file name. The traceback for the exception was written to the log file, and I think it's because it doesn't run all the lines in the same terminal.

How can I make this work? I'm using Ubuntu 16.04

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
Dylan
  • 29
  • 5

2 Answers2

0

If you're sure your control flow is correct (i.e. it prints HIGH/LOW when appropriate), I imagine the problem here is that you're executing your commands in separate calls to os.system which executes them in seperate shells. Try this:

position = "low"
if marker.pose.position.z > 1 and position=="low":
    os.system("cd ~/catkin_ws_artag/src/launch && roslaunch pr2_indiv_1.launch")
    posicion = "high"
    print "HIGH"
    ################################
if marker.pose.position.z < 1 and position=="high":
    os.system("cd ~/catkin_ws_artag/src/launch && roslaunch pr2_indiv_0.launch")
    posicion = "low"
    print "LOW"
Tim
  • 2,123
  • 4
  • 27
  • 44
  • It works well, but I don't know if what I'm doing is correct. I'm receiving information in marker.pose.position.z at a frequency of 30 Hz (i.e., 30 messages per second). I need to use two different detectors, one when marker.pose.position.z < 0.3, for example, and the other one when it's higher. But I can't use both detectors at the same time. The detector is the ar_track_alvar from ROS. I don't know if what I'm doing is the best, because it takes some microseconds to execute the detector. Maybe adding some sleep or something like that would be good? – Dylan Mar 05 '19 at 01:34
0

If you need to execute multiple shell commands, you could put them all first in a shell script.

ros-commands.sh

#!/bin/bash

LAUNCH_FILE=$1

cd ~/catkin_ws_artag/src/launch
roslaunch $1

Make sure it's executable (i.e. chmod +x ros-commands.sh).
Then place that in the same directory as your Python script.

gino:ros$ ls
total 8
-rw-rw-r-- 1 gino gino 59  3月  5 13:18 your-python-script.py
-rwxrwxr-x 1 gino gino 74  3月  5 13:14 ros-commands.sh

In your Python script, call the shell script.
(Using the most active answer from How to call a shell script from python code?)

your-python-script.py

import subprocess

position = "low"
if marker.pose.position.z > 1 and position=="low":
    subprocess.call(['./ros-commands.sh', "pr2_indiv_1.launch"])
    position = "high"
    print "HIGH"
    ################################
if marker.pose.position.z < 1 and position=="high":
    subprocess.call(['./ros-commands.sh', "pr2_indiv_0.launch"])
    position = "low"
    print "LOW"

In this way:

  1. You can extend the shell script if you need to add other ROS-related commands (ex. you mentioned adding sleep in the other answer)
  2. You can test your shell script separately
  3. It solves the problem of "it doesn't run all the lines in the same terminal"
Gino Mempin
  • 25,369
  • 29
  • 96
  • 135