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

Initial state and goals are incorrectly generated in problem file by PDDLProblemGenerator #253

Open
dgerod opened this issue Jun 30, 2020 · 1 comment
Assignees

Comments

@dgerod
Copy link
Contributor

dgerod commented Jun 30, 2020

Now that I am moving my code from using old ROSPlan version to the latest one, I have realized about this issue.

The "makeInitialState()" method of "PDDLProblemGenerator" writes parameters of a predicate following the order in which they are stored in KB, but this is wrong. And same problem is happening in "makeGoals()". The parameters of a predicate could be stored in any order in the KB because they have name, but the problem file generated is wrong due to this assumption.

My domain:

(define (domain organize_items)
(:requirements :typing :disjunctive-preconditions)
(:types
    place
    object
    container - place
    item - object
    box - place
)
(:predicates
	(robot-at ?p - place)
	(object-at ?o - object ?p - place)
	(localised ?o - object)
	(grasped ?o - object)
	(free-tool)
)
... MORE_CODE_HERE ...
)

The correct generated problem file should be:

(define (problem task)
(:domain organize_items)
(:objects
    home - place
    c1 - container
    item_0 item_2 item_1 item_3 - item
    b1 - box
)
(:init
    (robot-at home)
    (object-at item_0 c1)
    (object-at item_2 c1)
    (object-at item_1 c1)
    (object-at item_3 c1)
    (free-tool)
)
(:goal (and
    (object-at item_0 b1)
    (object-at item_2 b1)
    (object-at item_1 b1)
    (object-at item_3 b1)
))
)

Generated problem file:

(:init
    (robot-at home)
    (object-at c1 item_0)
    (object-at c1 item_2)
    (object-at c1 item_1)
    (object-at c1 item_3)
    (free-tool)
)
(:goal (and
    (object-at b1 item_0)
    (object-at b1 item_2)
    (object-at b1 item_1)
    (object-at b1 item_3)
))

As this is is not happening in the old version of ROSPlan, I have compared both codes. The makeInitialState() in the new version of ROSPlan is:

std::vector<rosplan_knowledge_msgs::DomainFormula>::iterator ait = domainAttrSrv.response.items.begin();
for(; ait != domainAttrSrv.response.items.end(); ait++) {

	rosplan_knowledge_msgs::GetAttributeService attrSrv;
	attrSrv.request.predicate_name = ait->name;
	if (!getPropsClient.call(attrSrv)) {
		ROS_ERROR("KCL: (PDDLProblemGenerator) Failed to call service %s: %s", state_proposition_service.c_str(), attrSrv.request.predicate_name.c_str());
	} else {

		for(size_t i=0;i<attrSrv.response.attributes.size();i++) {

			rosplan_knowledge_msgs::KnowledgeItem attr = attrSrv.response.attributes[i];

			pFile << "    (";		
			
			//Check if the attribute is negated
			if(attr.is_negative) pFile << "not (";

			pFile << attr.attribute_name;
			for(size_t j=0; j<attr.values.size(); j++) {
				pFile << " " << attr.values[j].value;
			}
			pFile << ")";
			
			if(attr.is_negative) pFile << ")";

			pFile << std::endl;
		}
	}
	pFile << std::endl;

	... MORE_CODE_HERE ...
}

While in the old version there is the code after "// find the PDDL parameters in the KnowledgeItem". And in my understanding it is this code which guarantees to write the parameters of the predicates in the correct order.

// add knowledge to the initial state
for(size_t i=0; i<environment.instance_attributes.size(); i++) {

	std::stringstream ss;
	bool writeAttribute = false;
	
	// check if attribute is a PDDL predicate
	std::map<std::string,std::vector<std::string> >::iterator ait;
	ait = environment.domain_predicates.find(environment.instance_attributes[i].attribute_name);
	if(ait != environment.domain_predicates.end()) {
		writeAttribute = true;
		ss << "    (" + environment.instance_attributes[i].attribute_name;

		// find the PDDL parameters in the KnowledgeItemAs conclusion, in 
		for(size_t j=0; j<ait->second.size(); j++) {
			bool found = false;
			for(size_t k=0; k<environment.instance_attributes[i].values.size(); k++) {
				if(0 == environment.instance_attributes[i].values[k].key.compare(ait->second[j])) {
					ss << " " << environment.instance_attributes[i].values[k].value;
					found = true;
				}
			}
			if(!found) writeAttribute = false;
		};
		ss << ")";
	}
	if(writeAttribute) pFile << ss.str() << std::endl;
}

Same code could be found in "makeGoals()" of old version of ROSPlan.

Therefore, my conclusion is that this is a bug. Please, could someone confirm it? Thanks.

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

2 participants