LAPKT-dev / LAPKT-public

LAPKT public repository
GNU General Public License v3.0
40 stars 24 forks source link

How to serialise current problem to textfile? #10

Closed Napoleon-BlownApart closed 8 years ago

Napoleon-BlownApart commented 9 years ago

I'm new to LAPKT and would like to know if/how one can output a text file (in something close to PDDL format) of a problem that is currently loaded in a STRIPS_Problem variable. I know something similar can be for actions using the action's signature method, can this be done for the whole problem?

I need to be able to insert new ground atoms, into an existing problem, that are discovered in the world the agent is working in.

Cheers, Nap

miquelramirez commented 9 years ago

Hello and nice to meet you! :)

yes, you can. Check out the method print() of class STRIPS_Problem. That will print on the designated input output stream the ground atoms and operators resulting from grounding a given PDDL input.

There are several ways what you want to do can be achieved. Note that in order to compute efficiently heuristics a number of auxiliary data structures are built every time the method make_action_tables() of STRIPS_Problem is called. So changing the set of fluents associated with a given STRIPS_Problem instance can be tricky. Creating a new STRIPS_Problem instance and "dumping" into it the atom and action set of the previous one, plus new atoms and actions is quite straightforward.

Cheers,

Miquel.

Napoleon-BlownApart commented 9 years ago

Good morning Miquel, Thank you for your reply, I noticed that it's been a while since the last post here and wasn't sure how I would go with my question. So, it was a pleasure to read your comments.

I tried the print() method, but the output isn't formatted in PDDL, so I cannot use it directly as a problem definition.

My strategy at the moment is to be able to run problem definitions inside a loop, where I load a new Domain/Problem on each iteration. Then I have the option of dynamically altering the plan by adding atoms before build_orig_constant_list is executed in libff, or altering the problem definition file before its loaded by doing some customised manual parsing.

However, I've had problems running in a loop. :( When my loop comes around to its 2nd iteration, I get a segmentation fault that occurs while executing aptk::FF_Parser::get_problem_description. (I'm currently working through the code to figure out why this is happening.)

I've noticed that global variables are used a lot, and they are not cleared each time a new plan is loaded, and that aptk:FF_Parser is largely a static class.

To speed up my work, I decided to reduce my problem down to a dozen lines which results in 8 fluents & 6 actions, and to my surprise, the second pass worked. I don't yet know why this is so, and whenever I load my normal plan (which has 72 Fluents & 92 Actions) the segmentation fault comes back.

Cheers, Nap.

PS.. I was at RMIT quite some time ago where I studied CommEng.

nirlipo commented 9 years ago

Hi Nap,

A quick tip to debug FF_Parser, remember to recompile the library with debug flag -g (external/libff/makefile), as the Scons won't change this flag inside the library.

Keep us posted on your progress, we can help you spot the issue if you get stuck.

Kind Regards,

Nir

On Wed, Nov 4, 2015 at 10:47 AM, Napoleon-BlownApart < notifications@github.com> wrote:

Good morning Miquel, Thank you for your reply, I noticed that it's been a while since the last post here and wasn't sure how I would go with my question. So, it was a pleasure to read your comments.

I tried the print() method, but the output isn't formatted in PDDL, so I cannot use it directly as a problem definition.

My strategy at the moment is to be able to run new problem definitions inside a loop, where I load a new Domain/Problem on each iteration. Then I have the option of dynamically altering the plan by adding atoms before build_orig_constant_list is executed in libff, or altering the problem definition file before its loaded by doing some customised manual parsing.

However, I've had problems running in a loop. :( When my loop comes around to its 2nd iteration, I get a segmentation fault that occurs while executing aptk::FF_Parser::get_problem_description. (I'm currently working through the code to figure out why this is happening.)

I've noticed that global variables are used a lot, and they are not cleared each time a new plan is loaded, and that aptk:FF_Parser is largely a static class.

To speed up my work, I decided to reduce my problem down to a dozen lines which results in 8 fluents & 6 actions, and to my surprise, the second pass worked. I don't yet know why this is so, and whenever I load my normal plan (which has 72 Fluents & 92 Actions) I the segmentation fault comes back.

Cheers, Nap.

PS.. I was at RMIT quite some time ago where I studied CommEng.

— Reply to this email directly or view it on GitHub https://github.com/miquelramirez/LAPKT-public/issues/10#issuecomment-153526427 .

tobyodavies commented 9 years ago

Not all of the parser front-ends keep around enough information to reconstruct a pddl representation that has much relationship with the original problem. You might have more luck programmatically constructing and modifying your STRIPS_Problem to start with than trying to parse, dump and re-parse the pddl.

On 4 November 2015 at 10:47, Napoleon-BlownApart notifications@github.com wrote:

Good morning Miquel, Thank you for your reply, I noticed that it's been a while since the last post here and wasn't sure how I would go with my question. So, it was a pleasure to read your comments.

I tried the print() method, but the output isn't formatted in PDDL, so I cannot use it directly as a problem definition.

My strategy at the moment is to be able to run new problem definitions inside a loop, where I load a new Domain/Problem on each iteration. Then I have the option of dynamically altering the plan by adding atoms before build_orig_constant_list is executed in libff, or altering the problem definition file before its loaded by doing some customised manual parsing.

However, I've had problems running in a loop. :( When my loop comes around to its 2nd iteration, I get a segmentation fault that occurs while executing aptk::FF_Parser::get_problem_description. (I'm currently working through the code to figure out why this is happening.)

I've noticed that global variables are used a lot, and they are not cleared each time a new plan is loaded, and that aptk:FF_Parser is largely a static class.

To speed up my work, I decided to reduce my problem down to a dozen lines which results in 8 fluents & 6 actions, and to my surprise, the second pass worked. I don't yet know why this is so, and whenever I load my normal plan (which has 72 Fluents & 92 Actions) I the segmentation fault comes back.

Cheers, Nap.

PS.. I was at RMIT quite some time ago where I studied CommEng.

— Reply to this email directly or view it on GitHub https://github.com/miquelramirez/LAPKT-public/issues/10#issuecomment-153526427 .

miquelramirez commented 9 years ago

Hi Nap,

what Toby says, really. FF parser is meant to be setup once in a given process. For an example on how to setup a STRIPS_Problem programmatically check the example here

https://github.com/miquelramirez/LAPKT-public/blob/master/examples/agnostic-examples/assembling_strips_problems/main.cxx

For a more complex use case, check out this demo I prepared for my PhD defense

https://github.com/miquelramirez/pr-as-planning-demo.git


Funny, LAPKT first lines of code were laid when I was at RMIT :)

Cheers,

Miquel.

On Wed, 4 Nov 2015 11:18 Toby Davies notifications@github.com wrote:

Not all of the parser front-ends keep around enough information to reconstruct a pddl representation that has much relationship with the original problem. You might have more luck programmatically constructing and modifying your STRIPS_Problem to start with than trying to parse, dump and re-parse the pddl.

On 4 November 2015 at 10:47, Napoleon-BlownApart <notifications@github.com

wrote:

Good morning Miquel, Thank you for your reply, I noticed that it's been a while since the last post here and wasn't sure how I would go with my question. So, it was a pleasure to read your comments.

I tried the print() method, but the output isn't formatted in PDDL, so I cannot use it directly as a problem definition.

My strategy at the moment is to be able to run new problem definitions inside a loop, where I load a new Domain/Problem on each iteration. Then I have the option of dynamically altering the plan by adding atoms before build_orig_constant_list is executed in libff, or altering the problem definition file before its loaded by doing some customised manual parsing.

However, I've had problems running in a loop. :( When my loop comes around to its 2nd iteration, I get a segmentation fault that occurs while executing aptk::FF_Parser::get_problem_description. (I'm currently working through the code to figure out why this is happening.)

I've noticed that global variables are used a lot, and they are not cleared each time a new plan is loaded, and that aptk:FF_Parser is largely a static class.

To speed up my work, I decided to reduce my problem down to a dozen lines which results in 8 fluents & 6 actions, and to my surprise, the second pass worked. I don't yet know why this is so, and whenever I load my normal plan (which has 72 Fluents & 92 Actions) I the segmentation fault comes back.

Cheers, Nap.

PS.. I was at RMIT quite some time ago where I studied CommEng.

— Reply to this email directly or view it on GitHub < https://github.com/miquelramirez/LAPKT-public/issues/10#issuecomment-153526427

.

— Reply to this email directly or view it on GitHub https://github.com/miquelramirez/LAPKT-public/issues/10#issuecomment-153531679 .

Napoleon-BlownApart commented 9 years ago

I can certainly tell it was meant to be run as a one-shot process. But I want to be able to run it in a loop and I'm achieving that already. But I am only able to run 11 loops of my small plan (72 fluents and 92 actions) so far. (Enough for a demonstration for my thesis, but I want more.)

I'm getting a segmentation fault at strips_problem.set_domain_name( FF::get_domain_name() );, approx line 46 of ff_to_aptk.cxx. There is nothing wrong with that line, it's just that that's the point where the memory leaks become terminal.

Valgrind reports a problem with STRIPS_Problem::add_action, line 103 in strips_prob.cxx: Action* new_act = new Action( p );, as follows:

==6035== 458,436 (315,744 direct, 142,692 indirect) bytes in 1,012 blocks are definitely lost in loss record 284 of 285
==6035==    at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6035==    by 0x41F0F5: aptk::STRIPS_Problem::add_action(aptk::STRIPS_Problem&, std::string, std::vector<unsigned int, std::allocator<unsigned int> > const&, std::vector<unsigned int, std::allocator<unsigned int> > const&, std::vector<unsigned int, std::allocator<unsigned int> > const&, std::vector<aptk::Conditional_Effect*, std::allocator<aptk::Conditional_Effect*> > const&, float) (strips_prob.cxx:103)
==6035==    by 0x4336A7: aptk::FF_Parser::get_problem_description(std::string, std::string, aptk::STRIPS_Problem&, bool, bool) (ff_to_aptk.cxx:216)
==6035==    by 0x435511: main (parser.cpp:380)

I can't seem to make it go away because new_act is local and p.actions is empty by the time my 'clean-up' code is executed. I think it has to do with line 105: new_act->define( pre, add, del, ceffs ) Any ideas why or how to clean up the std::vector< std::pair<unsigned, unsigned> >?

Thanks for the example links!

I'm in agreement with Toby & yourself concerning the reconstruction of the PDDL from a loaded problem, so if I were to go down that path, I would end up modifying the original problem file (as I know how it's formatted). This is not a very good solution as it will only work for a specific example and require significant alterations to make it generalised.

Hence I'm trying to get my other approach going, where I modify an existing problem. From what I've understood of libff so far, I can do this by making my changes after its parsed the problem but before build_orig_constant_list gets executed. I'll have a look at your example code and see where it leads me.

Napoleon-BlownApart commented 9 years ago

I've realised that I need to perform some of the clean up at the end of the iteration, before I make the next call to aptk::FF_Parser::get_problem_description();. So now I have all the actions available for clean up.

miquelramirez commented 9 years ago

Hello,

Happy to hear you have sorted out the issue you were stuck on. Let us know if we can provide assistance - there's no point in grinding your wheels in the mud! :)

Miquel

On Thu, 5 Nov 2015 20:53 Napoleon-BlownApart notifications@github.com wrote:

I've realised that I need to perform some of the clean up at the end of the iteration, before I make the next call to aptk::FF_Parser::get_problem_description();. So now I have all the actions available for clean up.

— Reply to this email directly or view it on GitHub https://github.com/miquelramirez/LAPKT-public/issues/10#issuecomment-154010297 .

Napoleon-BlownApart commented 9 years ago

I have it running at least 1000 iterations. However it's with the same plan. I will now try altering the plan on each iteration. If you could send me a meaningful PDDL example, I would appreciate it. I only have the LAPKT examples and some other really simple ones.

Cheers, Nap

Napoleon-BlownApart commented 9 years ago

I've now tested it with two small problems; each with their own domain and problem. One has 2 agents that need to navigate past each other, the other is a simple navigation from point A to B for a single agent. I'm swapping them on each iteration (odd/even) and running for 1000 loops (ie each is calculated 500 times). The plans are correct for each iteration.

Done.

The strategy works! Thanks for the encouragement.

Napoleon-BlownApart commented 8 years ago

I've finished with my implementation and recorded a video. I thought you might be interested in having a look, so here is the link: https://www.youtube.com/watch?v=dOdFubN6jCI

The description of the video explains what I've done. It's nothing sophisticated, but it does work and demonstrates the protocol I was working on.

The planner calculates 4 plans throughout the video; at the start of each run, and once for each obstacle encountered. The terminal window above gedit is where the the planning software is running. I modified libff, as we've discussed in this thread, and also modified a little bit of LAPKT to allow the planner to remain in memory for the entire duration.

As a proof of concept, I made it possible to select between 3 of your searches; BFS_HMAX, BRFS, & DAS, and supply parameters to them via my protocol. It is simple to extend this to allow selection from all the searches you've developed. (I'm only using BFS_HMAX in the demo.)

The gedit window displays the discovered obstacles, the file is updated on the fly, but I only refresh/reloaded the file after the completion of the 1st run.

Cheers, Nap

nirlipo commented 8 years ago

Great to see it in action! Keep us updated on your thesis/application.

Regards,

Nir

On Sat, Nov 21, 2015 at 10:30 PM, Napoleon-BlownApart < notifications@github.com> wrote:

I've finished with my implementation and recorded a video. I thought you might be interested in having a look, so here is the link: https://www.youtube.com/watch?v=dOdFubN6jCI

The description of the video explains what I've done. It's nothing sophisticated, but it does work and demonstrates the protocol I was working on.

The planner calculates 4 plans throughout the video; at the start of each run, and once for each obstacle encountered. The terminal window above gedit is where the the planning software is running. I modified libff, as we've discussed in this thread, and also modified a little bit of LAPKT to allow the planner to remain in memory for the entire duration.

As a proof of concept, I made it possible to select between 3 of your searches; BFS_HMAX, BRFS, & DAS, and supply parameters to them via my protocol. It is simple to extend this to allow selection from all the searches you've developed. (I'm only using BFS_HMAX in the demo.)

The gedit window displays the discovered obstacles, the file is updated on the fly, but I only refresh/reloaded the file after the completion of the 1st run.

Cheers, Nap

— Reply to this email directly or view it on GitHub https://github.com/miquelramirez/LAPKT-public/issues/10#issuecomment-158629289 .

miquelramirez commented 8 years ago

It looks very good :)

BTW there's an implementation of FF Enforced Hill Climbing search in the toolkit as well - it is as close as Joerg's original implementation as it can get, and significantly faster.

Cheers,

Miquel.

On Sat, Nov 21, 2015 at 12:30 PM Napoleon-BlownApart < notifications@github.com> wrote:

I've finished with my implementation and recorded a video. I thought you might be interested in having a look, so here is the link: https://www.youtube.com/watch?v=dOdFubN6jCI

The description of the video explains what I've done. It's nothing sophisticated, but it does work and demonstrates the protocol I was working on.

The planner calculates 4 plans throughout the video; at the start of each run, and once for each obstacle encountered. The terminal window above gedit is where the the planning software is running. I modified libff, as we've discussed in this thread, and also modified a little bit of LAPKT to allow the planner to remain in memory for the entire duration.

As a proof of concept, I made it possible to select between 3 of your searches; BFS_HMAX, BRFS, & DAS, and supply parameters to them via my protocol. It is simple to extend this to allow selection from all the searches you've developed. (I'm only using BFS_HMAX in the demo.)

The gedit window displays the discovered obstacles, the file is updated on the fly, but I only refresh/reloaded the file after the completion of the 1st run.

Cheers, Nap

— Reply to this email directly or view it on GitHub https://github.com/miquelramirez/LAPKT-public/issues/10#issuecomment-158629289 .

Napoleon-BlownApart commented 8 years ago

Thanks Miquel, I will have a look at that. I've uploaded a couple more videos that specifically discuss the interaction between the planner and the e-Puck which might be of interest: e-Puck navigating a grid - Planner/e-Puck interface summary e-Puck navigating a grid - Planner/e-Puck interface summary (continued) In the first video, I simulate scenarios where the planner crashes or becomes unavailable, and in the second, where the e-Puck's interface to the planner crashes or becomes unavailable. Both of the videos have associated comments.

Cheers, Nap

miquelramirez commented 8 years ago

Good morning Napoleon,

Thanks for the videos, they were really enlightening and I appreciate that making these takes some time and effort. I may use them to illustrate some of the topics on planning featured on the AI course that I will teaching next semester.

Cheers,

Miquel

On Sat, 28 Nov 2015 13:29 Napoleon-BlownApart notifications@github.com wrote:

Thanks Miquel, I will have a look at that. I've uploaded a couple more videos that specifically discuss the interaction between the planner and the e-Puck which might be of interest: e-Puck navigating a grid - Planner/e-Puck interface summary https://www.youtube.com/watch?v=r84FC61aCTM e-Puck navigating a grid - Planner/e-Puck interface summary (continued) https://www.youtube.com/watch?v=EiTWIaT851g In the first video, I simulate scenarios where the planner crashes or becomes unavailable, and in the second, where the e-Puck's interface to the planner crashes or becomes unavailable. Both of the videos have associated comments.

Cheers, Nap

— Reply to this email directly or view it on GitHub https://github.com/miquelramirez/LAPKT-public/issues/10#issuecomment-160241782 .