Skip to content

Commit 705dd61

Browse files
Merge pull request #9 from NVIDIA-Jetson/sim_docker
Redtail Docker, APM rover and fixes
2 parents 468964a + 346d317 commit 705dd61

File tree

14 files changed

+638
-4
lines changed

14 files changed

+638
-4
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
# NVIDIA Redtail project
22

3-
Autonomous drone navigation using deep learning. Refer to [wiki](https://github.com/NVIDIA-Jetson/redtail/wiki) for more information on how to get started.
3+
Autonomous navigation for drones and ground vehicles using deep learning. Refer to [wiki](https://github.com/NVIDIA-Jetson/redtail/wiki) for more information on how to get started.
44

55
# News
6+
* **2017-10-12**: added full simulation Docker image, experimental support for APM Rover and support for MAVROS v0.21+.
7+
8+
* Redtail simulation Docker image contains all the components required to run full Redtail simulation in Docker. Refer to [wiki](../../wiki/Testing-in-Simulator) for more information.
9+
* Experimental support for APM Rover. Refer to [wiki](../../wiki#platforms) for more information.
10+
* Several other changes including support for MAVROS v0.21+, updated Jetson install script and few bug fixes.
11+
612
* **2017-09-07**: NVIDIA Redtail project is released as an open source project.
713

814
Redtail's AI modules allow building autonomous drones and mobile robots based on Deep Learning and NVIDIA Jetson TX1 and TX2 embedded systems.

ros/packages/px4_controller/include/px4_controller/px4_controller.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,27 @@ class PX4Controller
7979
float /*linear_control_val*/, float /*angular_control_val*/, bool /*has_command*/) override;
8080
};
8181

82+
class APMRover: public Vehicle
83+
{
84+
std::string getName() override { return "APMRover"; }
85+
std::string getOffboardModeName() override { return "MANUAL"; }
86+
bool init(ros::NodeHandle& nh) override;
87+
void printArgs() override;
88+
void executeCommand(const PX4Controller& ctl, const geometry_msgs::PoseStamped& goto_pose,
89+
float linear_control_val, float angular_control_val, bool has_command) override;
90+
private:
91+
float turn_angle_scale_ = 1;
92+
ros::Publisher rc_pub_;
93+
int rc_steer_trim_ = 1500;
94+
int rc_steer_dz_ = 30;
95+
int rc_steer_min_ = 1100;
96+
int rc_steer_max_ = 1900;
97+
int rc_throttle_trim_ = 1500;
98+
int rc_throttle_dz_ = 30;
99+
int rc_throttle_min_ = 1100;
100+
int rc_throttle_max_ = 1900;
101+
};
102+
82103
private:
83104
const int QUEUE_SIZE = 5;
84105
const int DNN_FRAME_WIDTH = 320;
@@ -101,8 +122,8 @@ class PX4Controller
101122
float doExpSmoothing(float cur, float prev, float factor) const;
102123
float getPoseDistance(geometry_msgs::PoseStamped& pose1, geometry_msgs::PoseStamped& pose2) const;
103124
geometry_msgs::Quaternion getRotationTo(geometry_msgs::Point& position, geometry_msgs::Point& target_position) const;
104-
geometry_msgs::Point computeNextWaypoint( geometry_msgs::PoseStamped& current_pose,
105-
float linear_control_val, float angular_control_val, float linear_speed) const;
125+
geometry_msgs::Point computeNextWaypoint(geometry_msgs::PoseStamped& current_pose,
126+
float linear_control_val, float angular_control_val, float linear_speed) const;
106127

107128
private:
108129
std::unique_ptr<Vehicle> vehicle_;

ros/packages/px4_controller/src/px4_controller.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,78 @@ void PX4Controller::Drone::executeCommand(const PX4Controller& ctl, const geomet
3939
ctl.local_pose_pub_.publish(goto_pose);
4040
}
4141

42+
bool PX4Controller::APMRover::init(ros::NodeHandle& nh)
43+
{
44+
nh.param("turn_angle_scale", turn_angle_scale_, 1.0f);
45+
46+
const int QUEUE_SIZE = 1;
47+
rc_pub_ = nh.advertise<mavros_msgs::OverrideRCIn>("/mavros/rc/override", QUEUE_SIZE);
48+
if(!rc_pub_)
49+
{
50+
ROS_INFO("Could not advertise to /mavros/rc/override");
51+
return false;
52+
}
53+
54+
auto get_param_client = nh.serviceClient<mavros_msgs::ParamGet>("/mavros/param/get");
55+
mavros_msgs::ParamGet param_get;
56+
param_get.request.param_id = "RC1_TRIM";
57+
if (get_param_client.call(param_get) && param_get.response.success)
58+
rc_steer_trim_ = (int)param_get.response.value.integer;
59+
nh.param("rc_steer_trim", rc_steer_trim_, rc_steer_trim_);
60+
61+
param_get.request.param_id = "RC1_DZ";
62+
if (get_param_client.call(param_get) && param_get.response.success)
63+
rc_steer_dz_ = (int)param_get.response.value.integer;
64+
nh.param("rc_steer_dz", rc_steer_dz_, rc_steer_dz_);
65+
66+
param_get.request.param_id = "RC3_TRIM";
67+
if (get_param_client.call(param_get) && param_get.response.success)
68+
rc_throttle_trim_ = (int)param_get.response.value.integer;
69+
nh.param("rc_throttle_trim", rc_throttle_trim_, rc_throttle_trim_);
70+
71+
param_get.request.param_id = "RC3_DZ";
72+
if (get_param_client.call(param_get) && param_get.response.success)
73+
rc_throttle_dz_ = (int)param_get.response.value.integer;
74+
nh.param("rc_throttle_dz", rc_throttle_dz_, rc_throttle_dz_);
75+
76+
return true;
77+
}
78+
79+
void PX4Controller::APMRover::printArgs()
80+
{
81+
ROS_INFO("(%s) Turn angle scale : %.1f", getName().c_str(), turn_angle_scale_);
82+
ROS_INFO("(%s) Steer trim : %d", getName().c_str(), rc_steer_trim_);
83+
ROS_INFO("(%s) Steer deadzone : %d", getName().c_str(), rc_steer_dz_);
84+
ROS_INFO("(%s) Steer min : %d", getName().c_str(), rc_steer_min_);
85+
ROS_INFO("(%s) Steer max : %d", getName().c_str(), rc_steer_max_);
86+
ROS_INFO("(%s) Throttle trim : %d", getName().c_str(), rc_throttle_trim_);
87+
ROS_INFO("(%s) Throttle deadzone: %d", getName().c_str(), rc_throttle_dz_);
88+
ROS_INFO("(%s) Throttle min : %d", getName().c_str(), rc_throttle_min_);
89+
ROS_INFO("(%s) Throttle max : %d", getName().c_str(), rc_throttle_max_);
90+
}
91+
92+
void PX4Controller::APMRover::executeCommand(const PX4Controller& ctl, const geometry_msgs::PoseStamped& goto_pose,
93+
float linear_control_val, float angular_control_val, bool has_command)
94+
{
95+
ROS_ASSERT(is_initialized_);
96+
97+
// REVIEW alexeyk: should not use RC override.
98+
mavros_msgs::OverrideRCIn rc_override;
99+
for (int c = 0; c < 8; c++)
100+
rc_override.channels[c] = mavros_msgs::OverrideRCIn::CHAN_NOCHANGE;
101+
int steer_delta = turn_angle_scale_ * angular_control_val;
102+
int steer_dz = steer_delta != 0 ? copysign(rc_steer_dz_, steer_delta) : 0;
103+
rc_override.channels[0] = rc_steer_trim_ + steer_dz + steer_delta;
104+
int throttle_delta = ctl.linear_speed_ * linear_control_val;
105+
int throttle_dz = throttle_delta != 0 ? copysign(rc_throttle_dz_, throttle_delta) : 0;
106+
rc_override.channels[2] = rc_throttle_trim_ + throttle_dz + throttle_delta;
107+
if(has_command)
108+
{
109+
ROS_DEBUG("APMRover::executeCommand: %d, %d (%.2f, %.2f)", (int)rc_override.channels[0], (int)rc_override.channels[2], linear_control_val, angular_control_val);
110+
rc_pub_.publish(rc_override);
111+
}
112+
}
113+
42114
void PX4Controller::px4StateCallback(const mavros_msgs::State::ConstPtr &msg)
43115
{
44116
fcu_state_ = *msg;
@@ -285,6 +357,8 @@ bool PX4Controller::parseArguments(const ros::NodeHandle& nh)
285357
nh.param<std::string>("vehicle_type", vehicle_type, "drone");
286358
if (vehicle_type == "drone")
287359
vehicle_ = std::make_unique<Drone>();
360+
else if (vehicle_type == "apmrover")
361+
vehicle_ = std::make_unique<APMRover>();
288362
else
289363
{
290364
ROS_ERROR("Unknown vehicle type: %s", vehicle_type.c_str());

ros/scripts/jetson_ros_install.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ catkin_make -DGSTREAMER_VERSION_1_x=On
129129
# Installing caffe_ros ROS package and its dependencies.
130130
echo "${green}Starting installation of caffe_ros and px4_controller ROS packages...${reset}"
131131
cd $HOME
132-
# REVIEW alexeyk: update with GitHub URL.
133132
if [ ! -d "$HOME/redtail" ]; then
134133
echo "Cloning caffe_ros sources..."
135134
git clone https://github.com/NVIDIA-Jetson/redtail
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
FROM ubuntu:14.04
2+
3+
# Build with:
4+
# docker build -t erle-sim:indigo -f Dockerfile.indigo .
5+
6+
ENV HOME /root
7+
8+
COPY scripts/* $HOME/scripts/
9+
RUN chmod +x -R $HOME/scripts/*
10+
RUN chown -R root:root $HOME/scripts/*
11+
12+
WORKDIR $HOME
13+
# Add repos:
14+
# ROS
15+
# Gazebo
16+
# DRC
17+
RUN apt-get update && apt-get install -y --no-install-recommends wget && \
18+
sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' && \
19+
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-key 0xB01FA116 && \
20+
sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -sc) main" > /etc/apt/sources.list.d/gazebo-stable.list' && \
21+
wget http://packages.osrfoundation.org/gazebo.key -O - | apt-key add - && \
22+
sh -c 'echo "deb http://packages.osrfoundation.org/drc/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/drc-latest.list' && \
23+
wget http://packages.osrfoundation.org/drc.key -O - | apt-key add - && \
24+
apt-get update
25+
26+
# Install required components first.
27+
RUN apt-get install -y --no-install-recommends \
28+
gawk make git curl cmake g++ \
29+
python-dev python-pip python-matplotlib \
30+
python-serial python-wxgtk2.8 python-scipy \
31+
python-opencv python-numpy python-pyparsing \
32+
python-setuptools ccache realpath \
33+
libopencv-dev libxml2-dev libxslt1-dev \
34+
lsb-release unzip libgl1-mesa-dri
35+
36+
# Python packages and MAVProxy
37+
RUN pip install wheel && \
38+
pip install future && \
39+
pip install pymavlink catkin_pkg --upgrade && \
40+
pip install MAVProxy==1.5.2
41+
42+
# ArUco
43+
RUN wget "https://downloads.sourceforge.net/project/aruco/OldVersions/aruco-1.3.0.tgz?ts=1494024608&use_mirror=cytranet" -O aruco-1.3.0.tgz && \
44+
tar -xvzf aruco-1.3.0.tgz && \
45+
cd aruco-1.3.0/ && \
46+
mkdir build && cd build && \
47+
cmake .. && \
48+
make -j `nproc` && \
49+
make install
50+
51+
# APM
52+
WORKDIR $HOME
53+
RUN mkdir -p simulation && \
54+
cd simulation && \
55+
git clone https://github.com/erlerobot/ardupilot -b gazebo
56+
57+
# ROS
58+
# Install and init ROS base and MAVROS
59+
RUN apt-get install -y ros-indigo-ros-base ros-indigo-mavros ros-indigo-mavros-extras && \
60+
rosdep init && \
61+
rosdep update && \
62+
echo "source /opt/ros/indigo/setup.bash" >> $HOME/.bashrc
63+
64+
# Install ROS packages
65+
RUN apt-get install -y --no-install-recommends python-rosinstall \
66+
ros-indigo-octomap-msgs \
67+
ros-indigo-joy \
68+
ros-indigo-geodesy \
69+
ros-indigo-octomap-ros \
70+
ros-indigo-mavlink \
71+
ros-indigo-control-toolbox \
72+
ros-indigo-transmission-interface \
73+
ros-indigo-joint-limits-interface \
74+
ros-indigo-image-transport \
75+
ros-indigo-cv-bridge \
76+
ros-indigo-angles \
77+
ros-indigo-polled-camera \
78+
ros-indigo-camera-info-manager \
79+
ros-indigo-controller-manager
80+
81+
# Install Gazebo
82+
WORKDIR $HOME
83+
RUN apt-get install -y --no-install-recommends gazebo7 libgazebo7-dev drcsim7
84+
85+
# Create ROS workspace
86+
WORKDIR $HOME
87+
RUN bash $HOME/scripts/init_workspace.bash
88+
89+
WORKDIR $HOME/simulation
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Running simulation in Docker for Erle Robotics vehicles
2+
3+
This repository contains scripts and instructions on building Docker container for the purpose of running simulations with [Erle Robotics](http://erlerobotics.com/) vehicles. It is essentially dockerized instructions provided on the official [Erle Robotics website](http://docs.erlerobotics.com/simulation). Currently only ROS Indigo is supported and tested, Kinetic is in the works.
4+
5+
## Building Docker image
6+
To build a Docker container, run the following command from this directory:
7+
```sh
8+
docker build -t erle-sim:indigo -f Dockerfile.indigo .
9+
```
10+
This command will create a Docker image with the tag ```erle-sim:indigo```. Once the build is finished, you can verify that the image is built by running ```docker images``` command.
11+
12+
## Creating Docker container
13+
In order to be able to run Gazebo from the Docker container, you need to connect host's X server to the Docker container. A good tutorial on various methods is documented on the [ROS Wiki](http://wiki.ros.org/docker/Tutorials/GUI), here we use the most simple (and insecure!) way.
14+
1. Create Docker container:
15+
```sh
16+
docker run -it --network=host -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix${DISPLAY} --name=erle-sim erle-sim:indigo bash
17+
```
18+
This command will create a container named ```erle-sim``` from the image with the same name (```erle-sim```) and enable executing GUI programs.
19+
2. Exit the container and restart/attach the container granting the permissions to xhost first:
20+
```sh
21+
xhost +local:`docker ps -aqf "name=erle-sim"`
22+
docker start erle-sim && docker attach erle-sim
23+
```
24+
Replace ```erle-sim``` with your container name if needed.
25+
3. Run Gazebo to make sure everything is working:
26+
```sh
27+
gazebo
28+
```
29+
You should see Gazebo window.
30+
### Troubleshooting
31+
In case you see messages like ```failed to load driver``` while executing step 3 **and** no Gazebo window opens up, you might be missing drivers. The current Docker script already contains command that installs Mesa drivers (```libgl1-mesa-dri```) but that might not be enough so try googling for more information.
32+
## Testing
33+
Once the container is created, try running simulator. For example, to run Rover simulator, run the following commands from the container:
34+
```sh
35+
source ~/simulation/ros_catkin_ws/devel/setup.bash
36+
cd ~/simulation/ardupilot/APMrover2/
37+
../Tools/autotest/sim_vehicle.sh -j 4 -f Gazebo
38+
# once MAVProxy has launched completely, load the parameters
39+
param load /[full_path_to_your_home_directory]/simulation/ardupilot/Tools/Frame_params/3DR_Rover.param
40+
# For example: param load /root/simulation/ardupilot/Tools/Frame_params/3DR_Rover.param
41+
```
42+
Now connect another terminal to the currently running Docker container:
43+
```sh
44+
docker exec -it erle-sim bash
45+
```
46+
and run the following commands:
47+
```sh
48+
source ~/simulation/ros_catkin_ws/devel/setup.bash
49+
roslaunch ardupilot_sitl_gazebo_plugin rover_spawn.launch
50+
```
51+
If everything was setup correctly, you should see Gazebo window with Rover model that you can control from the first terminal using MAVProxy commands:
52+
![Gazebo Erle Rover](./images/gazebo.png)
53+
Some of the MAVProxy commands are described [here](http://docs.erlerobotics.com/simulation/vehicles/erle_rover/tutorial_1).
54+
You can also use ```run_erle_sim.sh``` script to create new container or attach to a running container.
85.7 KB
Loading
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
ERLE_SIM_NAME=erle-sim
2+
ERLE_SIM_ID=`docker ps -aqf "name=^/${ERLE_SIM_NAME}$"`
3+
ERLE_SIM_HOST_DATA_DIR=/data/
4+
if [ -z "${ERLE_SIM_ID}" ]; then
5+
echo "Creating new Erle Sim container."
6+
docker run -it --network=host -v ${ERLE_SIM_HOST_DATA_DIR}:/data/:rw -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix${DISPLAY} --name=${ERLE_SIM_NAME} erle-sim:indigo bash
7+
else
8+
echo "Found Erle Sim container: ${ERLE_SIM_ID}."
9+
# Check if the container is already running and start if necessary.
10+
if [ -z `docker ps -qf "name=^/${ERLE_SIM_NAME}$"` ]; then
11+
xhost +local:${ERLE_SIM_ID}
12+
echo "Starting and attaching to Erle Sim container..."
13+
docker start ${ERLE_SIM_ID}
14+
docker attach ${ERLE_SIM_ID}
15+
else
16+
echo "Found running Erle Sim container, attaching bash to it..."
17+
docker exec -it --privileged ${ERLE_SIM_ID} bash
18+
fi
19+
fi
20+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/bin/bash
2+
#
3+
4+
# Stop in case of any error
5+
set -e
6+
7+
source /opt/ros/indigo/setup.bash
8+
9+
WDIR=`pwd`
10+
11+
# Create catkin workspace
12+
mkdir -p simulation/ros_catkin_ws/src
13+
cd simulation/ros_catkin_ws/src
14+
catkin_init_workspace
15+
cd ..
16+
catkin_make
17+
source devel/setup.bash
18+
19+
# Get packages
20+
cd $WDIR/simulation/ros_catkin_ws/src
21+
22+
git clone https://github.com/ros-drivers/driver_common
23+
git clone https://github.com/erlerobot/ardupilot_sitl_gazebo_plugin
24+
git clone https://github.com/erlerobot/rotors_simulator -b sonar_plugin
25+
git clone https://github.com/PX4/mav_comm.git
26+
git clone https://github.com/ethz-asl/glog_catkin.git
27+
git clone https://github.com/catkin/catkin_simple.git
28+
git clone https://github.com/erlerobot/mavros.git
29+
git clone https://github.com/ros-simulation/gazebo_ros_pkgs.git -b indigo-devel
30+
git clone https://github.com/erlerobot/gazebo_python_examples
31+
#git clone https://github.com/erlerobot/gazebo_cpp_examples
32+
#git clone https://github.com/tu-darmstadt-ros-pkg/hector_gazebo/
33+
34+
# Make packages
35+
cd ..
36+
catkin_make --pkg mav_msgs mavros_msgs gazebo_msgs
37+
source devel/setup.bash
38+
catkin_make -j `nproc`
39+
40+
# Gazebo models
41+
cd $WDIR
42+
mkdir -p .gazebo/models
43+
cd .gazebo/models
44+
git clone https://github.com/erlerobot/erle_gazebo_models

0 commit comments

Comments
 (0)