Using PyCharm Code Completion with a ROS2-Docker Environment

I've been trying to set up an environment for running ROS2 inside a docker container. I was able to successfully get some basic ROS2 code running inside the container, however, I am unable to get code completion to work for anything other than python packages I install via the Dockerfile.

According to the ROS2 documentation for IDEs (http://wiki.ros.org/IDEs): A similar problem is solved in linux by launching PyCharm from a shell that has sourced the ROS2 source.bash (source /opt/ros/<distro>/setup.bash).

I would like to know if there is a way to have PyCharm use the docker shell environment for code completion or perhaps a way to source the source.bash file from the docker container? Any advice is appreciated.

3
5 comments

After more investigation, I believe what I need is for the docker-compose remote interpreter to use the docker entrypoint for code completion? Not sure if that is possible or not.

0

I haven't tried this in ROS2 yet, but in ROS, for code completion, you don't necessarily need to source a set-up file as long as the python interpreter inside the container has the ROS-installed python packages in its path.  The easiest way I've found to accomplish this is to symlink the ROS packages from your interpreter's default site-packages location. The exact paths will differ depending on your particular environment, but the command should look something like this:
```ln -s /opt/ros/<ROSDISTRO>/lib/pythonX.X/dist-packages ~/local/lib/pythonX.X/site-packages/ros-packages```
then you need to add this symlink to the list of packages that should be loaded into the path by creating a .pth file in the site-packages directory:
```echo "ros-packages" > ~/local/lib/pythonX.X/site-packages/ros.pth```
This will allow the remote interpreter to build the skeletons for all of the rospy modules installed by your package manager, but it won't give you access to any new modules you are building in your catkin workspaces. You can do a similar thing for your local development environment by copying your workspace into Docker and doing a a full `catkin_make install` and symlinking to the workspace's install directory, but this still mandates you rebuild your image every time you want to propagate the changes in your workspace into the remote interpreter. I'm still looking for better ways to do this latter part.

2

The minimal `Dockerfile` that works for me:

FROM ros:foxy
WORKDIR /home/ubuntu/work/ros_ws
RUN apt-get update && apt-get install -y python3-pip && rm -rf /var/lib/apt/lists/*

# Source for PyCharm auto completetion (tested on PyCharm 2020.2)
RUN bash -c "source /opt/ros/$ROS_DISTRO/setup.bash"

# Source your code application
# RUN bash -c "source $DEV_WS/install/local_setup.bash"

Then I just add it as a Docker interpreter.

0

I'm not sure what your use case is, but with respect to the original question asked, that definitely wouldn't work. Nothing is populating or building the directory at /home/ubuntu/work/ros_ws, so the install/local_setup.bash file would not even exist in this container. With lines added for copying in a workspace and doing a colcon install, though, this still wouldn't work, because the consoles created when you RUN a command would be destroyed as soon as the command is finished. If you added these source lines to a bashrc, and set the ENTRYPOINT and USER appropriately in the Dockerfile, it still doesn't work, even in the in-editor Python console. I've tested the "trivial" solutions like this quite a bit and none of them play nice with Pycharm's helpers. 

One addendum to my earlier post: I now use an SSH interpreter with my local workspace volume-mapped into the container and the workspace's site packages defined in the .pth file similar to how I added ROS's default packages. This allows me to re-build generated code live from a terminal exec'd into the container, and see the skeletons update in Pycharm, outside the container, immediately afterwards. By adding my local workspace as a source directory in Pycharm, I can also ensure intellisense goes first into my own source files before searching the immutable skeletons generated in the container when I jump into an implementation/declaration. The downside is that I need to manually launch and manage the lifecycle of the container myself, but it's otherwise the ideal solution. There is a bunch of ssh-agent tomfoolery required when building the container to get a valid ssh key in and provide Pycharm the permissions it needs to install helpers. I may at some point be able to share a Dockerfile which demonstrates this. I'll revisit this thread and link to it when I'm able.

1

Hej Devook! Do you have any updates on your SSH-related workflow with ros-docker images and PyCharm? I think you found a very nice solution and the community would greatly appreciate it if you shared your workaround.

PS I am not an expert in docker nor remote SSH connection :- )

0

Please sign in to leave a comment.