Unity-Technologies / ROS-TCP-Endpoint

ROS package used to create an endpoint to accept ROS messages sent from a Unity scene using the ROS TCP Connector scripts
Apache License 2.0
185 stars 124 forks source link

Allow creating debian package #99

Open RafaelRey opened 3 years ago

RafaelRey commented 3 years ago

Is your feature request related to a problem? Please describe. When deploying a setup, it's very useful to be allow to directly use the package as a debian package. It gives precise control of the version that is currently used and allow dependent packages to install it automatically if the debian package is uploaded to an APT repository and the package is listed in some rosdep yaml file.

Describe the solution you'd like The package is almost ready to allow you create a working debian package of it using for example python-bloom tool. Four changes need to be apply:

  1. Add installs to CMakeLists.txt to install launch, config, requirements.txt and scripts:
   install(DIRECTORY launch/ DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch)
   install(DIRECTORY config/ DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/config)

   install(FILES requirements.txt DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
   catkin_install_python(PROGRAMS  scripts/<script_1>
                                   scripts/<script_2>
                                   scripts/<script_3>
                                   scripts/<script_4>
                                   scripts/<script_5>
............................................................
                                   setup.py
                                  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}

  )
  1. Add "std_msgs" ROS package and python packages to package.xml

    <exec_depend>std_msgs</exec_depend>
    <exec_depend>rospy</exec_depend>
    <exec_depend>python3-pip</exec_depend>
    <exec_depend>python3-venv</exec_depend>
    <exec_depend>virtualenv</exec_depend>
  2. Add a postinst file to automatically create the python virtual environment: The content will depend on the python or ROS versions that you want to support, but the basic structure could be the following (valid for ROS Noetic):

## Detect ROS version or if both ROS1 and ROS2 are installed and get the ros path <ros_path>. 
  cd <ros_path>/share/ros_tcp_endpoint
  python3 -m venv venv_tcp_endpoint > /dev/null
  sudo chown -R $(whoami) venv_tcp_endpoint
  source venv_tcp_endpoint/bin/activate
  pip3 install --upgrade pip
  pip3 install wheel
  pip3 install -r requirements.txt --no-cache-dir
  deactivate
  1. Configure launch to run scripts under the virtual environment: This is the most relevant change. Instead of manually activating the python virtual environment in the running console, it's necessary to automatically run the scripts with the virtual environment. For that purpose what I do right now with other packages is to create a top running generic script called for example default_server_endpoint_script.py

!/usr/bin/env python

import os import subprocess import sys from time import sleep

def is_venv(): return (hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))

arg='--venv'

args = sys.argv[1:]

path_to_venv = args[args.index(arg) + 1].rstrip('/')

if not is_venv(): python_bin = path_to_venv + "/bin/python" else: python_bin = sys.executable

dirname, filename = os.path.split(os.path.abspath(file)) script_file = dirname + "/default_server_endpoint.py"

try: s = subprocess.Popen([python_bin, script_file] + args) return_node = s.wait() exit(return_node)

except KeyboardInterrupt:

while s.poll() is None:
    sleep(5)

return_node = s.wait()
exit(return_node)
It implies also changing the way the node is executed in the launch:

```xml
<launch>
    <rosparam file="$(find ros_tcp_endpoint)/config/params.yaml" command="load"/>
    <node name="server_endpoint" pkg="ros_tcp_endpoint" type="default_server_endpoint_script.py" args="--venv  $(find ros_tcp_endpoint)/venv_tcp_endpoint --wait" output="screen" respawn="true" />
</launch>
  1. Optionally add a postrm file to delete the virtual environement after removing the package with apt remove command:
#!/bin/bash

if [ "$1" != "upgrade" ] ; then
    # GET ROS PACKAGE PATH 
    path="/opt/ros/<ROSDISTRO>/share/ros_tcp_endpoint"
    echo "Removing virtual enviroment files..."
    sudo rm -rf $path
    echo "Virtual enviroment removed in $path"

fi

Sorry because it's a little bit long but I think that this are the only necessary changes. I can create also a pull request with the changes.

Describe alternatives you've considered

Additional context Add any other context or screenshots about the feature request here.

vidurvij-Unity commented 3 years ago

Hi @RafaelRey, Thank you for your interest in using this package. Its a great suggestion to convert this package to a Debian package. We encourage users to contribute to our repos. Feel free to start a pull request. Vidur

vidurvij-Unity commented 3 years ago

Thanks for your pull request @RafaelRey. We will be reviewing this pull request soon and merge it as soon as possible. I have created a ticket [AIRO/1368] to track it internally.

github-actions[bot] commented 3 years ago

This issue has been marked stale because it has been open for 14 days with no activity. Please remove the stale label or comment on this issue, or the issue will be automatically closed in the next 14 days.

github-actions[bot] commented 2 years ago

This issue has been marked stale for 14 days and will now be closed. If this issue is still valid, please ping a maintainer.

RafaelRey commented 2 years ago

Pinging @vidurvij-Unity to avoid issue closing

JWhitleyWork commented 2 years ago

Is there a reason this can't be released to the ROS Build Farm using the typical package release process instead of requiring people to manually build the package?

sdiao commented 2 years ago

We are currently reviewing the changes in https://github.com/Unity-Technologies/ROS-TCP-Endpoint/pull/100.

mrpropellers commented 2 years ago

Is there a reason this can't be released to the ROS Build Farm using the typical package release process instead of requiring people to manually build the package?

@JWhitleyWork That's a good question and we can't really give a satisfactory answer. The vague justification is that there is a higher internal quality bar that we need to hit to apply for release as a Package, as opposed to simply pushing to our open source repository, and our codebase is not yet mature enough to be certified at that level.

Addendum: We may be able to get away with adding a hook to automatically build the .deb file on main merges, though, and add it to our releases page... if that sounds like something that would improve your and others' experience, I can bring it up with the team.