osrf / capabilities

Implements the concept of capabilities as part of the robots-in-concert system.
Other
8 stars 26 forks source link

Capabilities to automatically start when prerequisites met? #58

Open mikepurvis opened 10 years ago

mikepurvis commented 10 years ago

Example use case is a platform which has separate indoor and outdoor pose estimators: the indoor one starts automatically by default, but once the gps fix topic is alive, user has the option to shut down the indoor one and replace it with the outdoor one.

Further possibilities would have the user able to permanently change the default, perhaps by blacklisting the indoor estimator (file in etc?) or some other scheme less intense than having to uninstall the providing package.

bit-pirate commented 10 years ago

Example use case is a platform which has separate indoor and outdoor pose estimators: the indoor one starts automatically by default, but once the gps fix topic is alive, user has the option to shut down the indoor one and replace it with the outdoor one.

When you start a capability you always have the option of choosing the provider you like.

Further possibilities would have the user able to permanently change the default, perhaps by blacklisting the indoor estimator (file in etc?) or some other scheme less intense than having to uninstall the providing package.

Could you elaborate on the intention behind this? For example, do you want to make it easier for the user of capabilities (human or app)?

mikepurvis commented 10 years ago

Right now, there are two ways to launch things on a robot: manual roslaunch or some kind of background daemon/upstart job for the "base stuff", and a capability for the "app stuff".

My intent with this suggestion is to enable making the robot's base thinner and lighter by making it possible to implement much of the base stuff as self-starting capabilities—things which automatically launch as their dependencies come up, but which also expose themselves to the user as hot-swappable capabilities. This gives a user more control over what runs on a factory configured robot, without requiring them to either a) hack on apt-installed launch files, b) duplicate the entire robot's configuration in a source workspace.

There are various ways this problem can be addressed; using the capabilities server is one of several possibilities.

wjwwood commented 10 years ago

What dependencies of certain capabilities need to "become" available? In most of the systems I have imagined, the list of capabilities on a robot is relatively static. With the exception of adding new capabilities with apt-get and calling ~reload_capabilities on the capability server, but that might be what you are referring to?

If you just want some of the dependencies to start by default, I could imagine the capability_server having a list of Interface/Provider tuples to start by default when the capability_server starts.

mikepurvis commented 10 years ago

Our robots are far from static as each one has multiple optional accessories, and typically the driver for the supported accessories is already on the system.

A list of Interface/Provider tuples to start by default seems like it'd be a great first step. Would you see this as being a single master list in ROS_ETC_DIR?

wjwwood commented 10 years ago

Our robots are far from static as each one has multiple optional accessories, and typically the driver for the supported accessories is already on the system.

Sure, but I imagined that it must be handled at some configuration point (like what software to install for which configuration). Currently there is no way for a capability to detect if hardware is available or something like that. If the capability spec exists, then the capability_server will allow you to try and start it, anything more intelligent will require more information.

A list of Interface/Provider tuples to start by default seems like it'd be a great first step. Would you see this as being a single master list in ROS_ETC_DIR?

No, I was thinking rosparams, just like the black and white lists for capabilities as well as the default providers.

bit-pirate commented 10 years ago

If you like to just change the default providers, it might be a good idea to add a service to change this setting on runtime.

Right now, there are two ways to launch things on a robot: manual roslaunch or some kind of background daemon/upstart job for the "base stuff", and a capability for the "app stuff".

I'd like to point you to the app manager, which we use for the "app stuff". Capabilities are already integrated with it. That is, you can specify capability dependencies in your app (e.g. here), which are then automatically started, when starting the app.

So, you could implement a watchdog monitoring your robot's hardware and other configuration and then either tell the capability server directly to launch a specific set of capabilities or an app, which depends on that specific set of capabilities.

We actually discussed supporting "hot-swapping" of sensors when we started the develop of the capability server. For example, someone plugs in a 3D sensor, the robot recognises it and automatically makes the 3DSensor capability available. This is definitely an interesting addition for the future.

mikepurvis commented 9 years ago

Hey, just wanting to wake this one up— I'd like to understand better what the intention is with the std_capabilities package. It seems that something like the Diagnostics interface would be a prime example of an interface which you'd want the capability server to start automatically, either as soon as the roscore is up, or when the first /diagnostics publisher is created. A similar scenario exists with a diff drive platform's base controller package which would implement the DifferentialMobileBase interface.

In the short term, I can use a shim node to request these things be brought up from the capability server, but any further thoughts on a rosparam to specify default tuples? Given some design guidance, I may be able to work on a PR.

wjwwood commented 9 years ago

Sorry about the latency of communication, I haven't forgotten about you, I just haven't had time to respond.

I think the shim node is the best option right now, though I understand the use case for auto-starting capabilities. However, I don't clearly see how to capture that in any way other than with domain specific code in something like a "shim" node as you describe. I suppose you could just have a default set of capabilities which start with the server, but for the more complicated case like "when the first /diagnostics publisher is created" I think the only way is custom code. Trying to capture all the stimuli which might trigger a capability seems out of scope for the capability server itself.

mikepurvis commented 9 years ago

I've explored the shim node idea, and I'm now wondering about the possibility of dynamically supplied providers.

For example, by default a platform could have the std_capabilities/LaserSensor interface with no provider, but a hardware introspection node could be monitoring the robot and detect when a Hokuyo or SICK scanner is plugged in, dynamically adding them as providers of the LaserSensor interface. Then, when a higher-level capability (eg, navigation) has need of the laser scanner, it starts it up.

wjwwood commented 9 years ago

@mikepurvis I see your point. In a more generic sense we need the notion of "startable" for each provider. So when someone asks the capability_server to start the LaserSensor interface, it looks for the list of providers (which is static and based on the packages installed) and then prunes that list by the "start-able" attribute of each provider. Each provider can provide an executable which is run to see if the provider is start-able, such that the checking executable's return code indicates this. Then you could write a start-able checking script for the Sick provider which checks to see if the (a) Sick laser is there, either by hitting the system or by asking a "hardware monitoring process".

This sort of goes against the design so far though, because the idea was always that the robot developer who setup the robot would configure the providers with implementation specific information and no dynamic behavior would be needed. For example, lets say that you connect to a sensor over USB based on the hardware ID (because you have more than one and they are otherwise identical). So you connect to each and check the ID, then hard code the correct ID into the correct provider launch file. IP addresses would be another example, lets say that you want the main LaserSensor to be a particular laser on the network, then you could hard code the IP of that laser into the provider file.

I understand that this philosophy of static configuration doesn't make a very flexible system when you are reconfiguring the robot a lot, but that just wasn't what we were thinking of when we designed this. Another path is that we could make tools for more easily updating the static configuration on a robot. These tools would look at the system and pick several static configurations (maybe even using templates) and combine them to setup the robot's current configuration. These tools could be rerun when the configuration changes and the list of providers would change. This doesn't help when you are rapidly or often changing the configuration of the robot, but it does help when you have many different configurations but change the setup infrequently.

The benefit, from my perspective, of keeping the static configuration and augmenting with configuration tools is that you get efficient and simple execution of the capabilities at runtime, which is exactly what you want on a production system which is not changing. If at all possible I would like to provide the dynamic flexibility which is desired from you guys where the systems are changing frequently, but without sacrificing simplicity and efficiency for the static deployment case.

mikepurvis commented 9 years ago

Certainly we are back and forth on when the configuration should occur.

Building a "setup assistant"-like app for compositing together a robot's URDF and launch files is a nontrivial undertaking, so we/I have been trying to figure out how to make do with run-time and launch-time solutions.

I'm trying to imagine other scenarios which might demand capability providers be enabled or disabled— some possibilities:

FWIW, I'd prefer any kind of detection scheme to be based on a named Python class with a specified interface, rather than an executable with a return code.