jetson-containers icon indicating copy to clipboard operation
jetson-containers copied to clipboard

Navigation2 with Humble container on Jetson Nano

Open elgarbe opened this issue 7 months ago • 16 comments

Is it possible to build navigation2 stack on humble container on a jetson nano?

elgarbe avatar Nov 21 '23 12:11 elgarbe

Hi @elgarbe, I just tried following the nav2 build instructions from https://navigation.ros.org/development_guides/build_docs/index.html#released-distribution-binaries using dustynv/ros:humble-desktop-l4t-r32.7.1 , but was met with errors during rosdep like:

$ rosdep install -y --from-paths ./src --ignore-src

ERROR: the following packages/stacks could not have their rosdep keys resolved
to system dependencies:
nav2_bt_navigator: No definition of [behaviortree_cpp_v3] for OS version [bionic]
nav2_smac_planner: No definition of [ompl] for OS version [bionic]
nav2_util: No definition of [bond] for OS version [bionic]
nav2_behavior_tree: No definition of [behaviortree_cpp_v3] for OS version [bionic]
nav2_bringup: No definition of [slam_toolbox] for OS version [bionic]
nav2_lifecycle_manager: No definition of [diagnostic_updater] for OS version [bionic]
nav2_system_tests: No definition of [gazebo_ros_pkgs] for OS version [bionic]
nav2_mppi_controller: [xsimd] defined as "not available" for OS version [bionic]

So instead, I try it like this using rosinstall_generator (and excluding xsimd package, which could not be found)

# create a workspace in a directory that you have mounted into the container
cd /mount
mkdir -p ros2_ws/src
cd ros2_ws

# pull the nav2 sources
source /opt/ros/humble/install/setup.bash
export ROS_PACKAGE_PATH=${AMENT_PREFIX_PATH}
rosinstall_generator --deps --exclude RPP --rosdistro humble navigation2 > ros2.humble.nav2.rosinstall
vcs import src/ < ros2.humble.nav2.rosinstall

# install dependencies
apt-get update
rosdep install -y --ignore-src --from-paths src --rosdistro humble --skip-keys "xsimd"

# build nav2
colcon build --symlink-install --base-paths src --event-handlers console_direct+

It's building now, but will see if it hits an error around xsimd, and if that needs to be installed manually.

dusty-nv avatar Nov 21 '23 14:11 dusty-nv

I hope you make it work. I've tried with this file: https://github.com/ros-planning/navigation2/blob/humble/tools/underlay.repos uncomenting the repos and using vcs import, but I get a lot ament_cmake errors

I'm working on another sdcard with unofficial ubuntu 20.04, installing ros2 foxy now.

I'm wondering pros/cons about official ubuntu 18.04 and ros2 humble using docker and unofficial ubuntu 20.04 and ros2 foxy

elgarbe avatar Nov 21 '23 16:11 elgarbe

Hi @elgarbe, I just tried following the nav2 build instructions from https://navigation.ros.org/development_guides/build_docs/index.html#released-distribution-binaries using dustynv/ros:humble-desktop-l4t-r32.7.1 , but was met with errors during rosdep like:

$ rosdep install -y --from-paths ./src --ignore-src

ERROR: the following packages/stacks could not have their rosdep keys resolved
to system dependencies:
nav2_bt_navigator: No definition of [behaviortree_cpp_v3] for OS version [bionic]
nav2_smac_planner: No definition of [ompl] for OS version [bionic]
nav2_util: No definition of [bond] for OS version [bionic]
nav2_behavior_tree: No definition of [behaviortree_cpp_v3] for OS version [bionic]
nav2_bringup: No definition of [slam_toolbox] for OS version [bionic]
nav2_lifecycle_manager: No definition of [diagnostic_updater] for OS version [bionic]
nav2_system_tests: No definition of [gazebo_ros_pkgs] for OS version [bionic]
nav2_mppi_controller: [xsimd] defined as "not available" for OS version [bionic]

So instead, I try it like this using rosinstall_generator (and excluding xsimd package, which could not be found)

# create a workspace in a directory that you have mounted into the container
cd /mount
mkdir -p ros2_ws/src
cd ros2_ws

# pull the nav2 sources
source /opt/ros/humble/install/setup.bash
export ROS_PACKAGE_PATH=${AMENT_PREFIX_PATH}
rosinstall_generator --deps --exclude RPP --rosdistro humble navigation2 > ros2.humble.nav2.rosinstall

# install dependencies
apt-get update
rosdep install -y --ignore-src --from-paths src --rosdistro humble --skip-keys "xsimd"

# build nav2
colcon build --symlink-install --base-paths src --event-handlers console_direct+

It's building now, but will see if it hits an error around xsimd, and if that needs to be installed manually.

Is there some missing commands on your post? I've tried the same and rosinstall_generator --deps --exclude RPP --rosdistro humble navigation2 > ros2.humble.nav2.rosinstall generate the rosinstall file with all the repos, but there isn't command to pull them...

EDIT: vcs import ./src < ros2.humble.nav2.rosinstall

elgarbe avatar Nov 21 '23 16:11 elgarbe

Ah sorry, yes - vcs import src/ < ros2.humble.nav2.rosinstall

It failed to build though:

In file included from /opt/ros/humble/install/include/rclcpp/rclcpp/callback_group.hpp:24:0,
                 from /opt/ros/humble/install/include/rclcpp/rclcpp/any_executable.hpp:20,
                 from /opt/ros/humble/install/include/rclcpp/rclcpp/memory_strategy.hpp:25,
                 from /opt/ros/humble/install/include/rclcpp/rclcpp/memory_strategies.hpp:18,
                 from /opt/ros/humble/install/include/rclcpp/rclcpp/executor_options.hpp:20,
                 from /opt/ros/humble/install/include/rclcpp/rclcpp/executor.hpp:37,
                 from /opt/ros/humble/install/include/rclcpp/rclcpp/executors/multi_threaded_executor.hpp:25,
                 from /opt/ros/humble/install/include/rclcpp/rclcpp/executors.hpp:21,
                 from /opt/ros/humble/install/include/rclcpp/rclcpp/rclcpp.hpp:155,
                 from /mount/test/ros2_ws/src/navigation2/nav2_util/include/nav2_util/service_client.hpp:20,
                 from /mount/test/ros2_ws/src/navigation2/nav2_util/include/nav2_util/lifecycle_service_client.hpp:24,
                 from /mount/test/ros2_ws/src/navigation2/nav2_util/src/lifecycle_service_client.cpp:15:
/opt/ros/humble/install/include/rclcpp/rclcpp/client.hpp: In instantiation of ‘std::optional<std::variant<std::promise<typename ServiceT::Response::SharedPtr>, std::tuple<std::function<void(std::shared_future<typename ServiceT::Response::SharedPtr>)>, std::shared_future<typename ServiceT::Response::SharedPtr>, std::promise<typename ServiceT::Response::SharedPtr> >, std::tuple<std::function<void(std::shared_future<std::pair<typename ServiceT::Request::SharedPtr, typename ServiceT::Response::SharedPtr> >)>, typename ServiceT::Request::SharedPtr, std::shared_future<std::pair<typename ServiceT::Request::SharedPtr, typename ServiceT::Response::SharedPtr> >, std::promise<std::pair<typename ServiceT::Request::SharedPtr, typename ServiceT::Response::SharedPtr> > > > > rclcpp::Client<ServiceT>::get_and_erase_pending_request(int64_t) [with ServiceT = lifecycle_msgs::srv::GetState; typename ServiceT::Response::SharedPtr = std::shared_ptr<lifecycle_msgs::srv::GetState_Response_<std::allocator<void> > >; typename ServiceT::Request::SharedPtr = std::shared_ptr<lifecycle_msgs::srv::GetState_Request_<std::allocator<void> > >; int64_t = long int]’:
/opt/ros/humble/install/include/rclcpp/rclcpp/client.hpp:551:38:   required from ‘void rclcpp::Client<ServiceT>::handle_response(std::shared_ptr<rmw_request_id_s>, std::shared_ptr<void>) [with ServiceT = lifecycle_msgs::srv::GetState]’
/mount/test/ros2_ws/src/navigation2/nav2_util/src/lifecycle_service_client.cpp:102:1:   required from here
/opt/ros/humble/install/include/rclcpp/rclcpp/client.hpp:821:12: error: could not convert ‘value’ from ‘std::variant<std::promise<std::shared_ptr<lifecycle_msgs::srv::GetState_Response_<std::allocator<void> > > >, std::tuple<std::function<void(std::shared_future<std::shared_ptr<lifecycle_msgs::srv::GetState_Response_<std::allocator<void> > > >)>, std::shared_future<std::shared_ptr<lifecycle_msgs::srv::GetState_Response_<std::allocator<void> > > >, std::promise<std::shared_ptr<lifecycle_msgs::srv::GetState_Response_<std::allocator<void> > > > >, std::tuple<std::function<void(std::shared_future<std::pair<std::shared_ptr<lifecycle_msgs::srv::GetState_Request_<std::allocator<void> > >, std::shared_ptr<lifecycle_msgs::srv::GetState_Response_<std::allocator<void> > > > >)>, std::shared_ptr<lifecycle_msgs::srv::GetState_Request_<std::allocator<void> > >, std::shared_future<std::pair<std::shared_ptr<lifecycle_msgs::srv::GetState_Request_<std::allocator<void> > >, std::shared_ptr<lifecycle_msgs::srv::GetState_Response_<std::allocator<void> > > > >, std::promise<std::pair<std::shared_ptr<lifecycle_msgs::srv::GetState_Request_<std::allocator<void> > >, std::shared_ptr<lifecycle_msgs::srv::GetState_Response_<std::allocator<void> > > > > > >’ to ‘std::optional<std::variant<std::promise<std::shared_ptr<lifecycle_msgs::srv::GetState_Response_<std::allocator<void> > > >, std::tuple<std::function<void(std::shared_future<std::shared_ptr<lifecycle_msgs::srv::GetState_Response_<std::allocator<void> > > >)>, std::shared_future<std::shared_ptr<lifecycle_msgs::srv::GetState_Response_<std::allocator<void> > > >, std::promise<std::shared_ptr<lifecycle_msgs::srv::GetState_Response_<std::allocator<void> > > > >, std::tuple<std::function<void(std::shared_future<std::pair<std::shared_ptr<lifecycle_msgs::srv::GetState_Request_<std::allocator<void> > >, std::shared_ptr<lifecycle_msgs::srv::GetState_Response_<std::allocator<void> > > > >)>, std::shared_ptr<lifecycle_msgs::srv::GetState_Request_<std::allocator<void> > >, std::shared_future<std::pair<std::shared_ptr<lifecycle_msgs::srv::GetState_Request_<std::allocator<void> > >, std::shared_ptr<lifecycle_msgs::srv::GetState_Response_<std::allocator<void> > > > >, std::promise<std::pair<std::shared_ptr<lifecycle_msgs::srv::GetState_Request_<std::allocator<void> > >, std::shared_ptr<lifecycle_msgs::srv::GetState_Response_<std::allocator<void> > > > > > > >’
     return value;

Will try some other things, but it occurred to me that I don't think nav2 uses GPU? so yea, you could use it in a 20.04-based container and just install it the normal way (or use the upstream ROS containers)

dusty-nv avatar Nov 21 '23 19:11 dusty-nv

I made some progress. The first one is use this. Edit /opt/ros/humble/install/include/rclcpp/rclcpp/client.hpp and replace return value; with return std::move(value); Then I have to install several package, I think that they has to be installed with rosdep install but I'm not sure why didn't happend. EDIT I have to add --skip-keys "ignition-cmake2" --skip-keys "ignition-math6" to get rosdep install to work properly

I'm building a Dockerfile while running command on the docker container and solving problems.

What could it be the best way to make the change needed on client.hpp file?

BTW I have 35/58 package build right now.

elgarbe avatar Nov 21 '23 23:11 elgarbe

I'm trying to make a Dokerfile with nav2 build process, but I'm facing a problem:

FROM dustynv/ros:humble-ros-base-l4t-r32.7.1

RUN mkdir -p /root/nav2_ws/src
WORKDIR /root/nav2_ws

ENV ROS_PACKAGE_PATH=/opt/ros/humble/install

# ROS fundamentals
RUN apt-mark hold '*opencv*' \
    && apt-get update \
    && apt autoremove -y \
    && rosinstall_generator --deps --exclude RPP --rosdistro humble navigation2 > ros2.humble.nav2.rosinstall \
    && vcs import src/ < ros2.humble.nav2.rosinstall \
    # &&  sudo rosdep fix-permissions \
    &&  rosdep update

RUN rosdep install -y --ignore-src --from-paths src --rosdistro humble --skip-keys "xsimd" --skip-keys "ignition-cmake2" --skip-keys "ignition-math6"

The las RUN command returns several errors: ERROR: the following packages/stacks could not have their rosdep keys resolved in the image build process.

But, if I comment out that RUN command, build the image and run it, then inside the container a can run that command without errors. What am I missing?

elgarbe avatar Nov 22 '23 13:11 elgarbe

@elgarbe hmm, not entirely sure - if you put rosdep install -y --ignore-src --from-paths src --rosdistro humble --skip-keys "xsimd" --skip-keys "ignition-cmake2" --skip-keys "ignition-math6" in the RUN command above it (commented as "ROS fundamentals"), does it fail then? If so, I think it would point to an issue with files that were removed in that RUN command, but persist after it (due to how docker filesystem layers work)

Or is perhaps some networking issue difference between docker build and docker run modes?

dusty-nv avatar Nov 22 '23 16:11 dusty-nv

@elgarbe hmm, not entirely sure - if you put rosdep install -y --ignore-src --from-paths src --rosdistro humble --skip-keys "xsimd" --skip-keys "ignition-cmake2" --skip-keys "ignition-math6" in the RUN command above it (commented as "ROS fundamentals"), does it fail then? If so, I think it would point to an issue with files that were removed in that RUN command, but persist after it (due to how docker filesystem layers work)

Or is perhaps some networking issue difference between docker build and docker run modes?

This:

# ROS fundamentals
RUN apt-mark hold '*opencv*' \
    && apt-get update \
    && apt autoremove -y \
    && rosinstall_generator --deps --exclude RPP --rosdistro humble navigation2 > ros2.humble.nav2.rosinstall \
    && vcs import src/ < ros2.humble.nav2.rosinstall \
    # &&  sudo rosdep fix-permissions \
    &&  rosdep update \
    &&  rosdep install -y --ignore-src --from-paths src --rosdistro humble --skip-keys "xsimd" --skip-keys "ignition-cmake2" --skip-keys "ignition-math6"

also fail. I'm not sure why I have to run the image in bridge mode. Running in host mode doesn't work, I mean I don't have internet connection in host mode.

elgarbe avatar Nov 22 '23 16:11 elgarbe

I'm not sure why I have to run the image in bridge mode. Running in host mode doesn't work, I mean I don't have internet connection in host mode.

That's strange hmm, I haven't seen that before and always use --network=host. I wonder if you can set defaults in /etc/docker/daemon.json so that your preferred network gets used during docker build operations:

https://docs.docker.com/network/drivers/bridge/#configure-the-default-bridge-network https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file

Is your Jetson connected to the internet over wifi, ethernet, or are you on a micro-USB connection through a PC?

dusty-nv avatar Nov 22 '23 19:11 dusty-nv

I'm connected by ethernet cable to the same router as my PC. Extrange that vcs import src/ < ros2.humble.nav2.rosinstall requier internet connection and works as expected, but rosdep install -y --ignore-src --from-paths src --rosdistro humble --skip-keys "xsimd" --skip-keys "ignition-cmake2" --skip-keys "ignition-math6" doesn't.

elgarbe avatar Nov 22 '23 19:11 elgarbe

I wonder if rosdep uses different ports or something which are blocked or having some firewall issue, but yea strange. Sorry I don't know how to fix that.

dusty-nv avatar Nov 22 '23 19:11 dusty-nv

I forget to source the ROS distro.... This is the best I can make, it faild on some point but I'm not able to fix it. It seems to me that has to be related to gcc version, and I know almost nothing about c++.

FROM dustynv/ros:humble-ros-base-l4t-r32.7.1

RUN mkdir -p /root/nav2_ws/src
WORKDIR /root/nav2_ws

ENV ROS_PACKAGE_PATH=/opt/ros/humble/install

# ROS fundamentals
RUN apt-mark hold '*opencv*' \
    && apt-get update \
    && apt autoremove -y \
    && rosinstall_generator --deps --exclude RPP --rosdistro humble navigation2 > ros2.humble.nav2.rosinstall \
    && vcs import src/ < ros2.humble.nav2.rosinstall \
    && . /opt/ros/$ROS_DISTRO/install/setup.sh \
    && rosdep fix-permissions \
    && rosdep update \
    && rosdep install -y --ignore-src --from-paths src --rosdistro humble --skip-keys "xsimd" --skip-keys "ignition-cmake2" --skip-keys "ignition-math6"

RUN echo "Fixing client.hpp file" \
    && sed -i "s|return value|return std::move(value) |g" /opt/ros/humble/install/include/rclcpp/rclcpp/client.hpp \
    && echo "client.hpp fixed" \
    && echo "Building..." \
    && . /opt/ros/$ROS_DISTRO/install/setup.sh \
    && colcon build --symlink-install --base-paths src --event-handlers console_direct+

# ENV RMW_IMPLEMENTATION=rmw_fastrtps_cpp
# COPY ros_entrypoint.sh /
# ENTRYPOINT ["/ros_entrypoint.sh"]
CMD ["bash"]

elgarbe avatar Nov 22 '23 20:11 elgarbe

https://github.com/ros-planning/navigation2/issues/3984

elgarbe avatar Nov 23 '23 16:11 elgarbe

@dusty-nv starting from a custom ubuntu 20.04 image (https://github.com/Qengineering/Jetson-Nano-Ubuntu-20-image) is there a way to run ros2 humble on docker and install nav2 package?

elgarbe avatar Jan 02 '24 15:01 elgarbe

@elgarbe no idea about CUDA support on Nano 4GB with 20.04, it's unsupported. If you don't need CUDA for those nodes, you can just use the official ROS images from https://hub.docker.com/_/ros/ for running nav2 in those.

dusty-nv avatar Jan 02 '24 15:01 dusty-nv

Oh!! yes I can use my nodes without CUDA. I have limited experience with docker, thank for your patience answering my questions.

elgarbe avatar Jan 02 '24 15:01 elgarbe