iocchi / PetriNetPlans

Petri Net Plans library and applications
31 stars 15 forks source link

Fixing inconsitent IDs in ros bridge #8

Closed cdondrup closed 8 years ago

cdondrup commented 8 years ago

Closes #7

The ID for the goals was created from maxID which is static and has therefore been increased with every new instance of the ActionProxy class. Hence, the end goal never had the same id as the start goal for concurrent actions. I introduced a new variable iid (short for integer id) which saves maxID during the creation of the instance locally. I could have used a sstream to get the int from the id as well but that seemed unnecessarily complicated.

This fixes the inconsistent IDs between start and end but it does not solve the problem that end is not always sent. I'll investigate further on this issue.

P.S.: Sorry for the messed up indentation but the whole file is a wild mix of tabs an spaces.

cdondrup commented 8 years ago

OK, I found the other issue as well. Apparently, (have to admit that I am not that well versed in C++) if you define a variable in the namespace of the class it is globally accessible across instances. Before the active flag which determines if a action is active and if the end function should be called was defined in the ActionProxy.cpp in the namespace pnpros. I now moved it to the header file and made it a private variable of ActionProxy. Since a quick grep for active revealed that it is only used in this class, nothing should break but now all actions correctly send the end action as well. Before, for concurrent action, the action that was ended first set the active=false which for the second concurrent action meant that the end function was not executed. The output now correctly shows:

[ INFO] [1470238864.578067881]: Start: dummy wait 5 - ID: 1
[ INFO] [1470238864.680558846]: Start: dummy goto forward - ID: 2
[ INFO] [1470238869.701250279]: End: dummy wait 5 - ID: 1
[ INFO] [1470238869.801654910]: End: dummy goto forward - ID: 2
[ INFO] [1470238869.843844440]: Start: dummy say hello - ID: 3
[ INFO] [1470238869.945695414]: Start: dummy wait 2 - ID: 4
[ INFO] [1470238874.966291743]: End: dummy say hello - ID: 3
[ INFO] [1470238875.066659799]: End: dummy wait 2 - ID: 4
[ INFO] [1470238875.088419157]: Start: dummy wait 3 - ID: 5
[ INFO] [1470238880.208991527]: End: dummy wait 3 - ID: 5
[ INFO] [1470238880.231197595]: Start: dummy say bye - ID: 6
[ INFO] [1470238880.334757478]: Start: dummy wait 2 - ID: 7
[ INFO] [1470238885.355387017]: End: dummy say bye - ID: 6
[ INFO] [1470238885.455767515]: End: dummy wait 2 - ID: 7
[ INFO] [1470238885.497789758]: Start: dummy goto backward - ID: 8
[ INFO] [1470238885.599481549]: Start: dummy wait 5 - ID: 9
[ INFO] [1470238890.620123395]: End: dummy goto backward - ID: 8
[ INFO] [1470238890.720644491]: End: dummy wait 5 - ID: 9
iocchi commented 8 years ago

Hi, thanks for looking into these problems and for fixing them. I think all the modifications are correct. I do not use these features in the C++ version of the PNPActionServer, that's why I did not encounter such problems. But for sure your correction was needed. I am checking a few more things (including indentation due to many people working on this project in several years...) and then I'll merge this branch with the master one.

P.S. Is your PNPActionServer.py general purpose or application-specific? Can you send me this file (or put it in the repository)?

Thank you. L.

iocchi commented 8 years ago

Found PNPActionServer.py ;-))) I'll give a look at it...

cdondrup commented 8 years ago

Hi, I was starting to implement a sort of plugin server which allows you to easily register action servers by using pnp_plugin_server or pnp_simple_plugin_server.

They have the same arguments as the ActionServer and SimpleActionServer but automatically call a service that registers them with my pnp action server. Therefore you can just plug in any kind of component that you like. They are identified by name, e.g. for the goto action the server has to listen on /goto/goal etc. The goal is filled automatically from the parameters string splitting them based on the _. I also implemented a wait server can be used by default for all the wait actions. Examples of simple test servers using the new plugin structure can be found in this repository.

Currently it only works top down meaning that I did not implement feedback yet and the condition evaluation is still missing as well but I am working on this. I was also wondering if it is possible to use the output of the action server to determine if it was successful or not. Couldn't find that so far.

I also wrote a very simple wrapper for the pnpgen which currently allows to generate a PNP via a service call using a linear plan like goto_waypoint;say_hello|5. This PNP can then be sent to the /planToExec topic which I modified to either accept a pnml filename as before or a pnml xml as a string on a topic. I am currently testing this with a simple bridge from ROSplan using PDDL to create a linear PNP that is then executed on my pepper robot.

Hope that all makes sense. I will keep you in the loop and let you know once I finished the bottom up communication with the knowledge base and condition evaluation. I will also write documentation and usage instructions at some point ;)

cdondrup commented 8 years ago

Forgot to mention, all this works already. So I can create a knowledge base in ROSplan and a domain using PDDL. Once I give it a goal, it creates a plan which is then parsed and sent to the pnpgen ros module which returns the PNP xml as a string. This string is then sent to the /planToExec topic which triggers the execution. My plugin server calls the registered servers with the given names (if there are any) and the actions are then executed on the robot.

Just the back channel is missing and it needs a bit of clean-up. I also have to make sure that everything installs correctly, haven't tested that yet.