Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deploying/distributing a ROS2 application as a standalone (self-contained) package on Windows is difficult. (We need a Snap equivalent for Windows) #1514

Open
CraigBuilds opened this issue Jan 26, 2024 · 13 comments

Comments

@CraigBuilds
Copy link

CraigBuilds commented Jan 26, 2024

I have asked for advice on Robotics Stack Exchange, however, it seems that there is no standard way to do this.

Feature request

Add support for deploying/distributing standalone (self-contained) ros2 executables on Windows.

Feature description

Add the ability to bundle Python, ROS2, DDS, and other dependencies with the created executable. This way a download can be sent to users who are not software developers and do not have the ROS2 development environment set up. They should simply be able to double-click the .exe, and the ROS2 Node will run. This is similar to creating a Snap on Linux, however this is not supported on Windows. It should work for nodes created with rclcpp and rclpy.

Implementation considerations

The current solution I am using is to send a whole virtual machine (or send a physical computer) with the software installed on it to the user. This is very heavyweight, and sending a file or download link would be preferable. Other solutions are Docker for Windows, or to expect the user to set up the ROS2 environment beforehand. Both of these involve some software development experience.

If the nodes were developed using rclcpp I could experiment with static linking, however, I am using rclpy so this is out of the question.

I have had some luck using pyinstaller:

pyinstaller .\src\my_pkg\my_pkg\main.py --collect-all rclpy --collect-all rosidl_parser --collect-all rcl_interfaces --collect-all builtin_interfaces --collect-all std_msgs --add-data C:\dev\ros2_humble:ros2_humble -y

This creates a folder than can be zipped and sent to the user, which includes an executable (entry point is the "main.py" node) and the ros2_humble install directory which includes the setup.ps1 script. It also bundles the python interpreter and any other dependencies so it is a truly standalone executable. This could likely be improved further with pyinstaller hooks that will get the executable to run the setup.ps1 script first. I haven't tried it with a ROS2 node that depends on other local ros2 packages.

When this is run on the users computer it successfully runs rclpy.init(), but it fails during the creation of the Node because it cannot find the licence for RTI connext. I use RTI Connext on my PC, but since the user does not have the environment variables set I assumed it would use the default RMW (which should be contained in the ros2_humble directory).

A ROS2 installer creator would be even better. It would be great if there was a supported utility that will help me create a graphical installer that I can send to users, and this will install the robot code (the nodes I developed) and all of the ROS2/DDS dependencies. This installer could also be used to simplify the install process of ROS2 for software developers, instead of having to follow a multi-step install document.

Final questions

Is this something that the ros2 developers would consider supporting? Are there any workarounds or other solutions I can use in the meantime, or perhaps advice with using pyinstaller? How have others distributed ROS2 code to users in the past?

@fujitatomoya
Copy link

I do not know very much Windows, but

Other solutions are Docker for Windows, or to expect the user to set up the ROS2 environment before-hand.

Why?

tomoyafujita@~/DVT >docker run --rm ros:humble ros2 topic pub /chatter std_msgs/String "data: Hello Windows"
publisher: beginning loop
publishing #1: std_msgs.msg.String(data='Hello Windows')

publishing #2: std_msgs.msg.String(data='Hello Windows')

publishing #3: std_msgs.msg.String(data='Hello Windows')

...

it can start the ROS 2 application with one line? (the above CLI example is on linux, but it should be similar?)

@CraigBuilds
Copy link
Author

CraigBuilds commented Jan 26, 2024

Why?

The cost. Unfortunately Docker on Windows requires Docker Desktop, which requires a paid subscription for companies with more than 250 employees.

Also, it's been a while since I used Docker on Windows (before they changed the subscription model), but my memory of it was that it was not as good as the Linux version, and had many problems. This may have changed now to be fair.

And finally, it would be even better if the user didn't have to install any other pieces of software before using the ROS2 application that has been given to them. Even installing something like Docker adds complexity, certainly when they are used to being able to launch software from their computer with a click of a button. Most people who are not software engineers do not know what Docker is or understand the point of it. In fact, even using a command line is foreign to many people.

@fujitatomoya
Copy link

The cost. Unfortunately Docker on Windows requires Docker Desktop

okay, i thought you have the concern about environment setup.

it would be even better if the user didn't have to install any other pieces of software before using the ROS2 application that has been given to them

i am not really following this... i mean even with snap, we need to install snapd?
if that requirement comes down to application framework, each framework would have own application deployment procedure?
i am not sure if that is really useful for the user space application...
maybe i am mistaken, we can keep this open more feedback.

@clalancette
Copy link
Contributor

For what it is worth, you are absolutely right. Installing ROS 2 on Windows today is very long, tedious, and error-prone.

However, I don't think it is as simple as providing an executable. While that would help the user to get the core of ROS 2, one of the huge benefits of ROS in general is the ecosystem. On Linux, for instance, you can choose from thousands of packages to install, that will help you with manipulation, navigation, embedded systems, ground truth, etc.

Eventually we'd like to get there with Windows as well. I think the most promising thing we could do would be to switch to something like Robostack, which would allow us to provide that same experience on Windows. Unfortunately we haven't had a lot of time to work on this, so it is just an idea at this point.

If you are interested in helping, I think the best thing you could do would be to get in touch with the Robostack people and see how you could help. In particular, it looks like only about 30-50% of packages currently build on Robostack, and Robostack only supports Humble at the moment. It would be best if more of those packages built and worked, and Robostack also supported Iron and Rolling.

@CraigBuilds
Copy link
Author

CraigBuilds commented Jan 29, 2024

i am not really following this... i mean even with snap, we need to install snapd?

That's true, but I think there could be an even better solution than snaps. Also, linux users tend to be more comfortable with the command line and having to install dependencies.

if that requirement comes down to application framework, each framework would have own application deployment procedure?
i am not sure if that is really useful for the user space application...
maybe i am mistaken, we can keep this open more feedback.

I think comparing ROS2 to other middleware frameworks will clarify why I think there is an issue. Let's say I developed my application with opc-ua as the middleware between all of the components. I could compile or package the result into plain old executables and the user wouldn't even know it was using opc-ua. I believe this is a very desirable property, and ROS2 should have this as well. The robot operator (for example, a welding and cutting engineer, a crane operator, or other specialist), should not need to know the software they are using is built using ROS2. I should be able to send them my GUIs, my simulators, my front end for ROS Bag, my supervisory nodes, the control system nodes, gateways, etc, and they should be able to start them up on their own computer and use them. They care about the function of the app, not that it is using ROS2. This isn't always an issue, e.g, code running on an industrial PC in a work cell that can be set up, locked up, and then tell people to never touch it (but it would be nice if I didn't have to do that), but for "office use" applications - e.g, the exact same nodes but using a simulator instead of the real robot, it becomes much more of an issue.

Another way of thinking about it: I can play Rocket League without installing Unreal Engine first. Why can't I use a ROS2 Node without installing ROS2 first?

As I've said, the best solution I have found so far is to give users virtual machines, but it is a very heavyweight solution and it does not feel like a polished experience.

@CraigBuilds
Copy link
Author

CraigBuilds commented Jan 30, 2024

Thank you for your reply @clalancette.

Robostack sounds interesting, I hadn't heard of that so thank you for the link. We will also look into contributing.

However, I don't think it is as simple as providing an executable.

To clarify, I am not suggesting providing ROS2 as an executable, but asking for the ability to turn applications that use ROS2 into standalone applications that do not need ROS2 installed first. (i.e static-linking, bundled etc).

I agree that having the full ROS ecosystem is beneficial for some. However I think it's useful to think about the types of users more broadly, and not all users will benefit from being able to tap into the wider ROS ecosystem.

I think the vast majority of ROS2 users are robotics engineers, software engineers, or researchers. However, there are many more potential users out there who interact with robots (and other hardware) at a higher level. They are unaware of the software frameworks or how it works, but they could benefit from the digital tools that can be used with robots. You could perhaps call these two user types API-Users and End-Users.

Some examples of these users (some are real, some are made up for the sake of this post):

A team of robotics and software engineers (api-users) deliver a robotics facility, control system, graphical user interfaces, and training tools, to a waste management site. The team at the waste management site (end-users) use the graphical user interfaces (which uses ROS2) to control the robots. They also have visualization tools, logging tools, planning tools etc, all which use ROS2 yet can be used without knowing what ROS2 is. There are also simulators that publish the same ROS2 data as the robots. These can be used in an office alongside the same digital tools used for the real operations. This office set-up is a particular pain point as the end-users do not have the expertise needed to install the dependencies.

A homeowner buys a robotic vacuum cleaner. They use an app to control the cleaner, schedule cleaning times, and monitor its progress. The homeowner interacts with a user-friendly interface, which, unbeknownst to them, communicates with the cleaner through ROS2. They can install 3rd party tools to expand their vacuum's capability.

An agricultural technician uses a tablet to control a drone for crop monitoring. The drone, equipped with ROS2 for flight control and data processing, collects and sends back real-time data on crop health. The technician, focusing on agricultural expertise rather than robotics, utilizes this data for farm management decisions.

@mjcarroll
Copy link
Member

To clarify, I am not suggesting providing ROS2 as an executable, but asking for the ability to turn applications that use ROS2 into standalone applications that do not need ROS2 installed first. (i.e static-linking, bundled etc).

In addition to robostack/pixi/conda, I think it would be interesting to see an extension/alternative to colcon-bundle that would allow you to generate a bundle of files necessary for runtime deployment of a ROS system. I believe that currently, colcon-bundle really only works on Linux, but could be extended to other operating systems.

@CraigBuilds
Copy link
Author

I have also recently been told about:

https://github.com/ms-iot/msix_ros

This is another project with a potential solution to deploy/distribute ROS2 on Windows.

@traversaro
Copy link

traversaro commented Feb 21, 2024

Some examples of these users (some are real, some are made up for the sake of this post):

A team of robotics and software engineers (api-users) deliver a robotics facility, control system, graphical user interfaces, and training tools, to a waste management site. The team at the waste management site (end-users) use the graphical user interfaces (which uses ROS2) to control the robots. They also have visualization tools, logging tools, planning tools etc, all which use ROS2 yet can be used without knowing what ROS2 is. There are also simulators that publish the same ROS2 data as the robots. These can be used in an office alongside the same digital tools used for the real operations. This office set-up is a particular pain point as the end-users do not have the expertise needed to install the dependencies.

A homeowner buys a robotic vacuum cleaner. They use an app to control the cleaner, schedule cleaning times, and monitor its progress. The homeowner interacts with a user-friendly interface, which, unbeknownst to them, communicates with the cleaner through ROS2. They can install 3rd party tools to expand their vacuum's capability.

An agricultural technician uses a tablet to control a drone for crop monitoring. The drone, equipped with ROS2 for flight control and data processing, collects and sends back real-time data on crop health. The technician, focusing on agricultural expertise rather than robotics, utilizes this data for farm management decisions.

I may be wrong, but (unless I am missing something, and in that case please correct me) ROS 2 (as of early 2024) is not the appropriate technology to do something like that, beside any kind of technical deployment issue such as the one described here. In general two different piece of software that use different versions of ROS 2 and/or different RMW may not communicate appropriately (see https://docs.ros.org/en/rolling/Concepts/Intermediate/About-Different-Middleware-Vendors.html#multiple-rmw-implementations, ros2/ros2_documentation#3288, https://discourse.ros.org/t/ros-2-tsc-meeting-minutes-2023-02-16/29927). The fact that in the future there will be official supported non-DDS RMW will make this even worse.

I do not want to say that this may never happen in the future, but given my limited experience it seems to me that ROS 2 as of early 2024 typically used in system where the system integration as full control on all the parts that communicate over ROS 2, and this is also the reason why most (even officially vendor supported) ROS 2 drivers are available in source form, as it would be quite tricky for vendors to ship a piece of hardware or a binary software that just uses ROS 2 out-of-the-box . When you are integrating pieces of software and/or hardware that you can't modify (typically you can just configure them), based on my limited experience protocols defined by strictly defined standards are typically used, like MQTT, OPC UA or any industrial fieldbus. Note that also in the case of strictly defined standards you can have bugs related to interoperability between different implementations, but those are typically considered by everyone bugs, and there exists practice to try to minimize those (such as OPC UA Compliance Test Tool for OPC UA).

Sorry for the OT, I still think that it would be cool to simplify deployment of Windows software using ROS 2, I am just afraid that it would not magically provide interoperability between closed software provided by different non-coordinated vendors.

@CraigBuilds
Copy link
Author

CraigBuilds commented Feb 28, 2024

@traversaro, thank you for your response. Your perspective is intriguing. My colleagues and I assessed the TRL of ROS2 following a training course and discussions with ROS Industrial and other industry representatives who participated in the course. We determined that the TRL of ROS2 meets our criteria. Consequently, we used ROS2 as our integration solution, opting for it over OPC UA, MQTT, or a combination of field buses and gateways.

The issue of RMW compatibility was overcome by prescribing one RMW that is compatible with our system, and documenting that future extensions must also use this. We also use none-ros2 components in our system that use DDS, so we were restricted to that vendor's version of DDS from the start anyway.

Interoperability between closed software provided by different non-coordinated vendors

I think this could be achieved. You can apt-install a ros2 node on Linux (which could be closed source), and as far as I'm aware, this will work with any RMW. It could work the same on Windows. The user installs the ROS2 node (likely using an installer, the idiomatic way to install programs for non-technical users on Windows), and this will also install the ROS2 dependencies if required, along with the default RMW. Another installer could be used for installing and setting the current RMW in use. Incorrectly configured components would not be interoperable, but this could be solved with documentation. i.e. "If you use our product, you must use this RMW". ROS2 isn't providing interoperability here, it is the RMW, however, ROS2 applications should work with any RMW.

@gavanderhoorn
Copy link

gavanderhoorn commented Feb 28, 2024

ROS2 isn't providing interoperability here, it is the RMW, however, ROS2 applications should work with any RMW.

re: different RMWs could be used, and are a configuration item that could be left to the end-user: technically: agreed.

In practice though I've found it's too easy for ROS 2 nodes to embed (implicit) assumptions about the behaviour of a particular RMW, thereby making a switch to another RMW (even if both/all are DDS-based) non-trivial.

(and that's even ignoring nodes which "go around" RCLC(PP)/PY to reach into the DDS-RMW layer(s) to make use of 'advanced' functionality or settings)

In addition to the posts & issues linked by @traversaro, this has also come up here (especially the "not all nodes will always be under your control" aspect) and the linked ros2/rmw_cyclonedds#184.


@gavanderhoorn wrote:

In practice though I've found it's too easy for ROS 2 nodes to embed (implicit) assumptions about the behaviour of a particular RMW, thereby making a switch to another RMW (even if both/all are DDS-based) non-trivial.

Edit: I fully expect other commenters to respond to this with "yes, but of course you shouldn't do that".

And, technically, they'd be correct.

Reality however sometimes makes this difficult/impossible.

@traversaro
Copy link

traversaro commented Feb 28, 2024

Interoperability between closed software provided by different non-coordinated vendors

I think this could be achieved. You can apt-install a ros2 node on Linux (which could be closed source), and as far as I'm aware, this will work with any RMW. It could work the same on Windows. The user installs the ROS2 node (likely using an installer, the idiomatic way to install programs for non-technical users on Windows), and this will also install the ROS2 dependencies if required, along with the default RMW. Another installer could be used for installing and setting the current RMW in use. Incorrectly configured components would not be interoperable, but this could be solved with documentation. i.e. "If you use our product, you must use this RMW". ROS2 isn't providing interoperability here, it is the RMW, however, ROS2 applications should work with any RMW.

Interesting. I think this is a case in which vendors are indeed coordinated, as they need to agree on the RMW to use, but I guess that that boils down to the definition of "coordinated", that I guess it is not an interesting topic of discussion. Correct me if I am wrong, but I guess the vendors would also need to agree on the ROS 2 distro to use (see https://answers.ros.org/question/341372/can-nodes-from-different-ros-2-distributions-communicate-compatibly)? In that case what do you imagine that the long term maintenance aspect of that would work? You would effectively not have ROS 2 as standard, but ROS2-Given-RMW-Given-Distro, and if you want to update all the non-coordinated vendors should provide the software for the update. That seems complex, but perhaps I am overthinking it.

To be super-clear, I think that ROS2 is really great, I am just not sure if I would like to use it as interface to closed source components that I may not be able to update in the future.

@CraigBuilds
Copy link
Author

Correct me if I am wrong, but I guess the vendors would also need to agree on the ROS 2 distro to use (see https://answers.ros.org/question/341372/can-nodes-from-different-ros-2-distributions-communicate-compatibly)? In that case what do you imagine that the long term maintenance aspect of that would work?

Exactly, ROS2-Given-RTI-Given-Humble is our standard. For long-term maintenance (~50 years), we will maintain a fork of Humble and RTI RMW. Virtual machines will be used to run this software. (Which going full circle, contradicts the fact that I'm looking for an alternative to virtual machines for deployment. I guess I'm looking for an alternative deployment method to use as well as the virtual machines, for the short term).

That seems complex, but perhaps I am overthinking it.

Not overthinking IMO. This is generating good discussion, which is what I wanted when I made this post. There isn't much discussion around ROS2 and deployments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants