Skip to content

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

Description

@dgerod

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions