diff --git a/midca/.idea/inspectionProfiles/Project_Default.xml b/midca/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 00000000..e96f6e02
--- /dev/null
+++ b/midca/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/midca/.idea/vcs.xml b/midca/.idea/vcs.xml
new file mode 100644
index 00000000..6c0b8635
--- /dev/null
+++ b/midca/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/midca/.idea/workspace.xml b/midca/.idea/workspace.xml
index 3ec6f10d..b637ee2b 100644
--- a/midca/.idea/workspace.xml
+++ b/midca/.idea/workspace.xml
@@ -1,111 +1,17 @@
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
makeframegraph
@@ -118,29 +24,10 @@
CURRENT_GOALS
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -185,20 +72,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -210,433 +85,4 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/midca/api/Midca_Domain_API.py b/midca/api/Midca_Domain_API.py
new file mode 100644
index 00000000..183d6ab9
--- /dev/null
+++ b/midca/api/Midca_Domain_API.py
@@ -0,0 +1,341 @@
+from __future__ import print_function
+import sys
+import os
+import csv
+import fileinput # supports inplace editing
+import argparse # handles cmd line args and verbose logging levels
+import shutil # file copying
+
+from collections import defaultdict
+
+middleware = 'UNDEFINED' # for generating middleware specific code
+
+directedGraph = defaultdict(list)
+attributes = defaultdict(list)
+enumerationList = []
+attributeValues = defaultdict(list)
+relations = defaultdict(list)
+entityRelations = defaultdict(list) # associates relations to the key of entity
+actions = defaultdict(list)
+
+# all inherited values for each entity
+inheritedAttributes = defaultdict(list)
+inheritedRelations = defaultdict(list)
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Graph Functions
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+#Adds node to the directedGraph
+def addEdge(directedGraph, u, v):
+ directedGraph[u].append(v)
+
+#Adds the directional relationship between objects
+def generate_edges(directedGraph):
+ edges = []
+ # for each node in directedGraph
+ for node in directedGraph:
+ # for each relation node of a single node
+ for relation in directedGraph[node]:
+ # if edge exists then append
+ edges.append((node, relation))
+ return edges
+
+#function that prints out the enumeration list of attributes with index values
+def printEnumerationList(enumerationList):
+ for idx, (object, attribute) in enumerate(enumerationList):
+ print("index is %d, name is %s, and attribute is %s"
+ % (idx, object, attribute))
+
+#main function that reads in a file of data and creates a directed tree of types
+#and directed tree of attributes as well as an enumeration list of attributes
+def objectInput(directedGraph, enumerationList, config):
+ index = 0
+ #create directed graph tree off of information provided in document
+ configFile = open(config)
+ fileText = csv.reader(configFile, delimiter = ',')
+ for row in fileText:
+ if row[0] == "middleware":
+ global middleware
+ middleware = row[1].lower() # auto lowercase
+ #if it is a type it is added to the type tree
+ elif row[0] == "type":
+ directedGraph[row[2]].insert(index, row[1])
+ index += 1
+ #if it is an attribute, then add it to the attribute tree
+ #and enumeration list
+ elif row[0] == "attribute":
+ attributes[row[1]].insert(index, row[2])
+ tempTupple = (row[2], row[1])
+ enumerationList.append(tempTupple)
+ elif row[0] == "attributeValue":
+ for value in row[2:]: # for each value in the action
+ attributeValues[row[1]].insert(index, value)
+ elif row[0] == "relation":
+ for type in row[2:]: # for each type in the relationship
+ relations[row[1]].insert(index, type)
+ entityRelations[row[2]].append(row[1]) # add relation as a child of the first entity
+ elif row[0] == "action":
+ for topic in row[2:]: # for each topic in the action
+ actions[row[1]].insert(index, topic)
+
+ configFile.close()
+
+
+def printPDDL(directedGraph):
+ # print PDDL types
+ print('\t(:types')
+ for node in directedGraph:
+ #print('' + node)
+
+ for relation in directedGraph[node]:
+ print('\t ' + relation + ' -' + node)
+
+ print('\t)\n')
+
+
+# prints tree with DFS
+def printTree(directedGraph, node, printAttributesBool):
+ visited = set() # Set to keep track of visited nodes.
+ attrib = attributes[node]
+
+ dfsPrint(visited, directedGraph, node, 0, printAttributesBool, attrib)
+
+
+def dfsPrint(visited, graph, node, depth, printAttributesBool, attrib):
+ if node not in visited:
+ print('\t' * depth + '+-- ' + node)
+ attrib = attrib + attributes[node]
+ if printAttributesBool:
+ print('\t' * depth + ' ' + (str)(attributes[node])) # print only specific attributes
+ visited.add(node)
+ for child in graph[node]:
+ dfsPrint(visited, graph, child, depth + 1, printAttributesBool, attrib)
+
+# accumulate inherited attributes with DFS
+def accumulateAttributes(directedGraph, node):
+ visited = set() # Set to keep track of visited nodes.
+ attrib = attributes[node]
+ eRelations = entityRelations[node]
+
+ dfsAccumulate(visited, directedGraph, node, attrib, eRelations)
+
+
+def dfsAccumulate(visited, graph, node, attrib, eRelations):
+ if node not in visited:
+ attrib = attrib + attributes[node]
+ eRelations = eRelations + entityRelations[node]
+ visited.add(node)
+
+ #only save accumulated attributes for leaf nodes
+ if len(graph[node]) == 0:
+ inheritedAttributes[node] = attrib
+ inheritedRelations[node] = eRelations
+ #print('{}: {}'.format(node, inheritedAttributes[node]))
+ #print('{}: {}'.format(node, inheritedRelations[node]))
+
+ for child in graph[node]:
+ dfsAccumulate(visited, graph, child, attrib, eRelations)
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Writing Templates
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+def modifyDetectors(filename):
+ file = fileinput.FileInput(filename, inplace=True)
+ #file = fileinput.FileInput(filename) # test output
+
+ for line in file:
+ if '' in line:
+ print(line.replace('', filename.replace('Detectors.cpp', '')), end='')
+
+ # Add methods for each entity in domain
+ elif '' in line:
+ for attrib in inheritedAttributes:
+ methodTxt = 'std::string detect_()\n{\n\t//TODO: create _attr string with the following attributes:\n\t//\n\n\treturn _attr;\n}\n'
+ methodTxt = methodTxt.replace('', attrib)
+ methodTxt = methodTxt.replace('', (str)(inheritedAttributes[attrib]))
+
+ print(methodTxt)
+ # Add topics for each entity in domain
+ elif '' in line:
+ for attrib in inheritedAttributes:
+ topicTxt = '\tros::Publisher _pub = n.advertise("_attr", 1);'
+ topicTxt = topicTxt.replace('', attrib)
+
+ print(topicTxt)
+ # Add publishers for each entity in domain
+ elif '' in line:
+ for attrib in inheritedAttributes:
+ publishTxt = '\t\t_pub.publish(_attr);'
+ publishTxt = publishTxt.replace('', attrib)
+
+ print(publishTxt)
+
+ else:
+ print(line, end='')
+
+ file.close()
+
+def modifyHandler(filename, domainName):
+ file = fileinput.FileInput(filename, inplace=True)
+ #file = fileinput.FileInput(filename) # test output
+ #print(' ')
+
+ for line in file:
+ if '' in line:
+ print(line.replace('', domainName), end='')
+
+ # Add relations for each entity in domain
+ elif '' in line:
+ for relate in inheritedRelations:
+ print(' #{}: {}'.format(relate, (str)(inheritedRelations[relate])))
+ else:
+ print(line, end='')
+
+ file.close()
+
+def modifyAsync(filename):
+ file = fileinput.FileInput(filename, inplace=True)
+ #file = fileinput.FileInput(filename) # test output
+
+ for line in file:
+ # Add topics for each operator in domain
+ if '' in line:
+ mergedTopics = []
+ for operator in actions:
+ mergedTopics = mergedTopics + actions[operator]
+ for topic in set(mergedTopics):
+ print(topic.upper() + '_TOPIC = \"' + topic + '\"')
+
+ # Add doOperator for each operator in domain
+ elif '' in line:
+ for operator in actions:
+ operatorText = fileinput.FileInput('templates/doOperatorTemplate.txt')
+ for text in operatorText:
+ if '' in text:
+ print(text.replace('', operator), end='')
+
+ # Add topics formats for each entity in domain
+ elif '' in text:
+ formats = ''
+ for topic in actions[operator]:
+ formats = formats + ('\'' + topic + '\': {},')
+ print(text.replace('', formats), end='')
+ else:
+ print(text, end='')
+ elif '' in line:
+ for operator in actions:
+ text = '\t\telif midcaAction[0] == \"\": \n\t\t\tcmdID = rosrun.next_id()\n\t\t\tactions.append((mem, midcaAction, midcaAction[1], \n\t\t\tallowed_sighting_lag(midcaAction[1]), allowed_sighting_wait(midcaAction[1]),\n\t\t\t, cmdID))'
+ text = text.replace('', operator)
+ text = text.replace('', (str)(actions[operator]))
+ print(text)
+ else:
+ print(line, end='')
+
+ file.close()
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Main
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+if __name__ == "__main__":
+ # manage args
+ parser = argparse.ArgumentParser()
+ parser.add_argument("config", help="domain specific configuration file")
+ parser.add_argument("-v","--verbosity",action="count",default=0,help="increase output verbosity")
+ args = parser.parse_args()
+
+ # parse all possible formats for .cfg path name
+ domainPathAppend = '../domains/'
+ domainPath = ''
+
+ if '../' not in args.config: # if cmd line arg does not include ../
+ domainPath = domainPath + '../'
+
+ if 'domains/' not in args.config: # if cmd line arg does not include domains/
+ domainPath = domainPath + 'domains/'
+
+ domainPath = domainPath + args.config # add at least domainName/ and .cfg filename
+
+ #determine domain name from passed filepath for arg
+ if not len(domainPath.split('/')) == 4:
+ print('Error: Config file must be located directly within domain directory')
+ sys.exit()
+
+ domainName = (domainPath.split('/'))[2]
+ #print(domainPath)
+ #print(domainName)
+
+ objectInput(directedGraph, enumerationList, domainPath) #generate config from passed file
+
+ # add output based on verbosity
+ if args.verbosity >= 1:
+ # print generated trees and edges
+ print("Edges of type tree: " + str(generate_edges(directedGraph)))
+ if args.verbosity >= 2:
+ print("Type Tree: " + (str)(directedGraph))
+
+ print("\nEdges of attribute tree: " + str (generate_edges(attributes)))
+ if args.verbosity >= 2:
+ print("Attribute Tree: " + (str)(attributes))
+ # printEnumerationList(enumerationList)
+
+ print("\nEdges of attributeValues tree: " + str (generate_edges(attributeValues)))
+ if args.verbosity >= 2:
+ print("Attribute Tree: " + (str)(attributeValues))
+
+ print("\nEdges of relations tree: " + str (generate_edges(relations)))
+ if args.verbosity >= 2:
+ print("Relations Tree: " + (str)(relations))
+
+ if args.verbosity >= 2:
+ print("\nActions Tree: " + (str)(actions))
+
+ # printPDDL(directedGraph)
+ if args.verbosity == 3:
+ #Future work: HAVE API ENFORCE ENTITY AS PARENT NODE
+ print('')
+ printTree(directedGraph, 'entity', False) # print entity tree without attributes
+ elif args.verbosity >= 4:
+ #Future work: HAVE API ENFORCE ENTITY AS PARENT NODE
+ print('')
+ printTree(directedGraph, 'entity', True) # print entity tree with attributes
+
+
+ accumulateAttributes(directedGraph, 'entity') # get all leaf nodes' inherited attributes
+
+ domainPath = domainPath.split('/')[0] +'/'+ domainPath.split('/')[1] +'/'+ domainPath.split('/')[2] # remove .cfg from this path
+
+
+ if middleware == "UNDEFINED":
+ print("Error: no middleware defined")
+ elif middleware == "ros":
+ if not os.path.exists(domainPath + "/ros"):
+ os.makedirs(domainPath + "/ros") # create the new ros sub-directory
+
+ # templates for each entity with their attributes for object detection code stubs and helpers
+ src='templates/detectorsTemplate.txt'
+ dst= domainPath + '/ros/' + domainName + 'Detectors.cpp'
+ shutil.copy(src,dst) # copy template to modify
+
+ modifyDetectors(dst)
+
+ # templates for each entity and their predicates for perception to determine relations
+ src='templates/entitiesHandlerTemplate.txt'
+ dst= domainPath + '/ros/' + domainName + 'EntitiesHandler.py'
+ shutil.copy(src,dst) # copy template to modify
+
+ modifyHandler(dst, domainName)
+
+ # templates for each action and their associated topics
+ src='templates/asyncTemplate.txt'
+ dst= domainPath + '/ros/' + domainName + '_async.py'
+ shutil.copy(src,dst) # copy template to modify
+
+ modifyAsync(dst)
+ else:
+ print("Error: no " + middleware + " implementation")
+
+
\ No newline at end of file
diff --git a/midca/api/templates/asyncTemplate.txt b/midca/api/templates/asyncTemplate.txt
new file mode 100644
index 00000000..abb93ee8
--- /dev/null
+++ b/midca/api/templates/asyncTemplate.txt
@@ -0,0 +1,244 @@
+from midca import rosrun, plans
+from midca import midcatime
+import traceback
+from midca.examples.homography import *
+import math
+import copy
+import numpy as np
+
+
+try:
+ from geometry_msgs.msg import PointStamped
+ from geometry_msgs.msg import Point
+ from midca.examples import ObjectDetector
+ from std_msgs.msg import String
+ from scipy.spatial import distance
+except:
+ pass #if ROS is not installed, an error message will already have been generated.
+
+
+END_COLOR_CODE = '\033[0m'
+NOT_STARTED = 0
+NS_COLOR_CODE = END_COLOR_CODE
+IN_PROGRESS = 1
+IP_COLOR_CODE = '\033[92m'
+COMPLETE = 2
+C_COLOR_CODE = '\033[94m'
+FAILED = 3
+F_COLOR_CODE = '\033[91m'
+FEEDBACK_KEY = "code"
+CMD_ID_KEY = "cmd_id"
+
+
+
+#set this to change output for all asynch actions.
+verbose = 2
+
+MAX_SIGHTING_LAG = 3.0
+MAX_SIGHTING_WAIT = 5.0
+
+def allowed_sighting_lag(objectID):
+ '''
+ returns how long ago an object can have been seen before MIDCA stops considering its
+ location known
+ '''
+ return MAX_SIGHTING_LAG
+
+def allowed_sighting_wait(objectID):
+ '''
+ returns the amount of midcatime MIDCA should wait to see an object before giving up.
+ '''
+ return MAX_SIGHTING_WAIT
+
+'''
+'''
+
+def get_asynch_action(midcaAction):
+ raise ArgumentException("midca action " + str(midcaAction) + " does not translate to a \
+ valid asynchronous action.")
+
+def asynch_plan(mem, midcaPlan):
+ '''
+ returns an asynchronous plan that corresponds to the given MIDCA plan.
+ '''
+ actions = []
+ goals = midcaPlan.goals
+ for midcaAction in midcaPlan.actions:
+ if midcaAction[0] == "block_until_seen":
+ actions.append(AwaitCurrentLocation(mem, midcaAction, midcaAction[1],
+ allowed_sighting_lag(midcaAction[1]), allowed_sighting_wait(midcaAction[1])))
+
+ else:
+ if verbose >= 1:
+ print "MIDCA action", midcaAction, "does not correspond to an asynch",
+ "action. MIDCA will skip this action"
+ return AsynchPlan(actions, goals)
+
+
+class AsynchPlan(plans.Plan):
+
+ '''
+ subclass of MIDCA Plan class that uses asynchronous actions.
+ '''
+
+ def finished(self):
+ '''
+ overrides plan.finished(). Declares a plan complete if all its actions report
+ complete or failed.
+ '''
+ for action in self.actions:
+ if action.status != COMPLETE and action.status != FAILED:
+ return False
+ return True
+
+ @property
+ def status(self):
+ '''
+ property that returns the plan's status. This can be NOT_STARTED, IN_PROGRESS,
+ FAILED, or COMPLETE. If any action fails, the plan is considered to have failed.
+ The plan is complete when all actions are complete.
+ '''
+ status = COMPLETE
+ for action in self.actions:
+ if action.status == FAILED:
+ return FAILED
+ elif action.status == NOT_STARTED and status == COMPLETE:
+ status = NOT_STARTED
+ elif action.status == IN_PROGRESS:
+ status = IN_PROGRESS
+ return status
+
+ def __str__(self):
+ s = ""
+ for action in self.actions:
+ if action.status == NOT_STARTED:
+ s += NS_COLOR_CODE
+ elif action.status == IN_PROGRESS:
+ s += IP_COLOR_CODE
+ elif action.status == FAILED:
+ s += F_COLOR_CODE
+ elif action.status == COMPLETE:
+ s += C_COLOR_CODE
+
+ s += str(action) + " "
+ return s[:-1] + END_COLOR_CODE
+
+class AsynchAction:
+
+ nextID = 0
+
+ def __init__(self, mem, midcaAction, executeFunc, isComplete, blocks):
+ self.status = NOT_STARTED
+ self.mem = mem
+ self.midcaAction = midcaAction
+ self.executeFunc = executeFunc
+ self.isComplete = isComplete
+ self.blocks = blocks
+ self.startTime = None
+ self.id = AsynchAction.nextID
+ AsynchAction.nextID += 1
+
+ def execute(self):
+ if not self.startTime:
+ self.startTime = midcatime.now()
+ self.status = IN_PROGRESS
+ if not self.executeFunc:
+ return
+ try:
+ self.executeFunc(self.mem, self.midcaAction, self.status)
+ except:
+ if verbose >= 2:
+ print "Error executing action", self, ":\n", traceback.format_exc(),
+ "\n\nAction assumed to be failed"
+ self.status = FAILED
+
+ def check_complete(self):
+ if not self.startTime:
+ self.startTime = midcatime.now()
+ if not self.check_complete:
+ return
+ try:
+ complete = self.isComplete(self.mem, self.midcaAction, self.status)
+ if verbose >= 2 and not complete:
+ print "Action", self, "not complete."
+ if verbose >= 1 and complete:
+ print "Action", self, "complete."
+ if complete:
+ self.status = COMPLETE
+ return complete
+ except:
+ if verbose >= 1:
+ print "Error checking completion status for action", self, " - Assuming \
+ failure:\n", traceback.format_exc()
+ self.status = FAILED
+
+ def ros_msg(self, topic, d):
+ '''
+ arg d should be a dictionary that contains the key/value pairs to be sent.
+ '''
+ sent = rosrun.send_msg(topic, rosrun.dict_as_msg)
+ if not sent:
+ if verbose >= 1:
+ print "Unable to send msg; ", d, "on topic", topic, " Action", self,
+ "assumed failed."
+ self.status = FAILED
+
+ def __str__(self):
+ return str(self.midcaAction)
+
+def get_last_position(mem, objectOrID):
+ state = mem.get(mem.STATE)
+ positions = state.all_pos(objectOrID)
+ if not positions:
+ return None
+ else:
+ for state_pos in reversed(positions):
+ if state_pos.position:
+ return (state_pos.position)
+ return None
+
+def get_last_location(mem, objectOrID):
+ world = mem.get(mem.STATE)
+ sightings = world.all_sightings(objectOrID)
+ if not sightings:
+ return None
+ else:
+ for detectionEvent in reversed(sightings):
+ if detectionEvent.loc:
+ return (detectionEvent.loc, detectionEvent.time)
+ return None
+
+
+
+
+class AwaitCurrentLocation(AsynchAction):
+
+ '''
+ Action that blocks until there is a current (within last maxAllowedLag seconds)
+ observation of the object's location.
+ '''
+
+ def __init__(self, mem, midcaAction, objectOrID, maxAllowedLag, maxDuration):
+ self.objectOrID = objectOrID
+ self.maxAllowedLag = maxAllowedLag
+ self.maxDuration = maxDuration
+ executeAction = None
+ completionCheck = lambda mem, midcaAction, status: self.completion_check()
+ AsynchAction.__init__(self, mem, midcaAction, executeAction,
+ completionCheck, True)
+
+ def completion_check(self):
+ t = midcatime.now()
+ if t - self.startTime > self.maxDuration:
+ if verbose >= 1:
+ print "max midcatime exceeded for action:", self, "- changing status to failed."
+ self.status = FAILED
+ return False
+ lastLocReport = get_last_location(self.mem, self.objectOrID)
+ if not lastLocReport:
+ return False
+ return t - lastLocReport[1] <= self.maxAllowedLag
+
+
+
+
diff --git a/midca/api/templates/detectorsTemplate.txt b/midca/api/templates/detectorsTemplate.txt
new file mode 100644
index 00000000..883fdeea
--- /dev/null
+++ b/midca/api/templates/detectorsTemplate.txt
@@ -0,0 +1,33 @@
+/*********************************************************************
+ *
+ *
+ * For example, consider using PointCloudLab
+ * (https://github.com/COLAB2/baxter_pcl/blob/master/src/detect_objects.cpp)
+ *
+ *
+ *********************************************************************/
+
+#include
+
+
+
+
+int main(int argc, char** argv)
+{
+ ROS_INFO_STREAM("Starting Entity Detectors node");
+
+ ros::init(argc, argv, "_entity_detectors");
+ ros::NodeHandle n;
+
+
+
+ while (ros::ok())
+ {
+
+
+ ros::spinOnce();
+ }
+
+ ros::spin();
+ return 0;
+}
\ No newline at end of file
diff --git a/midca/api/templates/doOperatorTemplate.txt b/midca/api/templates/doOperatorTemplate.txt
new file mode 100644
index 00000000..cc062e97
--- /dev/null
+++ b/midca/api/templates/doOperatorTemplate.txt
@@ -0,0 +1,60 @@
+class (AsynchAction):
+
+ def __init__(self, mem, midcaAction, objectOrID, maxAllowedLag, maxDuration, topics,
+ msgID):
+ self.objectOrID = objectOrID
+ self.maxAllowedLag = maxAllowedLag
+ self.maxDuration = maxDuration
+ self.lastCheck = 0.0
+ self.topics = topics
+ self.complete = False
+ self.msgID = msgID
+ # TODO: fill in formats for each topic
+ # Reference {'x': x, 'y': y, 'z': z, 'time': self.startTime, 'cmd_id': self.msgID}
+ self.topicFormats = {}
+
+ executeAction = lambda mem, midcaAction, status: self.send_point()
+ completionCheck = lambda mem, midcaAction, status: self.check_confirmation()
+ AsynchAction.__init__(self, mem, midcaAction, executeAction,
+ completionCheck, True)
+
+
+
+ def send_topic(self):
+
+ for topic in self.topics:
+ # Handle
+ self.msgDict = topicFormats[topic]
+
+ print self.msgDict
+
+ print "trying to send"
+ print topic
+
+ sent = rosrun.send_msg(topic, rosrun.dict_as_msg(self.msgDict))
+ if not sent:
+ if verbose >= 1:
+ print "Fail"
+ self.status = FAILED
+
+ def check_confirmation(self):
+ checkTime = self.lastCheck
+ self.lastCheck = midcatime.now()
+ feedback = self.mem.get(self.mem.FEEDBACK)
+ if not feedback:
+ return False
+ for item in reversed(feedback):
+ #if all items have been checked, either in this check or previous, return
+ if item['received_at'] - checkTime < 0:
+ return False
+ #else see if item is a completion or failure message with id == self.msgID
+ if item[CMD_ID_KEY] == self.msgID:
+ if item[FEEDBACK_KEY] == COMPLETE:
+ return True
+ elif item[FEEDBACK_KEY] == FAILED:
+ self.status = FAILED
+ if verbose >= 1:
+ print "MIDCA received feedback that action", self, "has failed"
+ return False
+ return False
+
diff --git a/midca/api/templates/entitiesHandlerTemplate.txt b/midca/api/templates/entitiesHandlerTemplate.txt
new file mode 100644
index 00000000..67a1646c
--- /dev/null
+++ b/midca/api/templates/entitiesHandlerTemplate.txt
@@ -0,0 +1,32 @@
+# https://github.com/COLAB2/midca/blob/c3e4cc9fab5683f44435816d90a7a2eb591c4ce4/midca/rosrun.py
+
+class EntitiesHandler(IncomingMsgHandler):
+
+ '''
+ class that receives Point messages, where each message indicates that the given object
+ has been identified at that location. Args include the topic to listen to, object id,
+ and midca object to whose memory observations will be stored. Optionally the memory
+ key to be stored to can also be specified.
+ '''
+
+ def __init__(self, topic, midcaObject, memKey = None, history = None):
+ callback = lambda strMsg: self.store(strMsg)
+ msgType = String
+ self.left = None
+ super(EntitiesHandler, self).__init__(topic, msgType, callback, midcaObject)
+ #self.objID = objID
+ if memKey:
+ self.memKey = memKey
+ else:
+ self.memKey = self.mem.ROS_OBJS_DETECTED
+ if history:
+ self.history = history
+ else:
+ self.history = self.mem.STATE_HISTORY
+
+ def store(self, data):
+ if not self.mem:
+ rospy.logerr("Trying to store data to a nonexistent MIDCA object.")
+
+ #TODO: Code should handle detecting the following relations (predicates):
+
\ No newline at end of file
diff --git a/midca/domains/New_Domain_Script.py b/midca/domains/New_Domain_Script.py
new file mode 100644
index 00000000..19c1b58c
--- /dev/null
+++ b/midca/domains/New_Domain_Script.py
@@ -0,0 +1,163 @@
+'''
+This is the start of the script for users to easily create domains from their .PDDL files
+Based on the file PDDL_util.py from Zoreh
+'''
+
+from __future__ import print_function
+import sys
+import inspect
+import shutil # copy file
+import os
+import re
+import argparse
+import fileinput # supports inplace editing
+
+
+# Setup for directory navigation
+newDomainName = ""
+thisDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
+MIDCA_ROOT = thisDir + "/../../"
+newDirectoryRoot = ""
+
+
+# Parsing function for PDDL to .sim
+def outermost_parentheses(input):
+ return re.search("\((.*)\)", input).group(1)
+
+
+# Parsing function for PDDL to .sim
+def parenthetic_contents(string):
+ """Generate parenthesized contents in string as pairs (level, contents)."""
+ stack = []
+ for i, c in enumerate(string):
+ if c == '(':
+ stack.append(i)
+ elif c == ')' and stack:
+ start = stack.pop()
+ yield (len(stack), string[start + 1: i])
+
+
+# Parsing function for PDDL to .sim
+def PDDL_to_MIDCA_DOMAIN(pddl_file, midca_file):
+ file = open(pddl_file, "r")
+ pddl = file.read()
+
+ elements = list(parenthetic_contents(pddl))
+ f = open(midca_file, 'w')
+
+ for (d, elm) in elements:
+ if (elm.startswith(":types")):
+ lines = elm.split("\n")
+ for line in lines[1:]:
+ if line.strip() != "":
+ f.write("type(" + line.split("-")[0].strip() + ")\n")
+
+ if (elm.startswith(":predicates")):
+
+ lines = parenthetic_contents(elm)
+ for (l, line) in lines:
+ objs = ""
+ types = ""
+ pairs = line.split("?")
+ f.write("\n predicate(" + pairs[0].strip() + ",")
+ for pair in pairs[1:]:
+ obj_type = pair.split("-")
+ objs = objs + "," + obj_type[0].strip()
+ types = types + "," + obj_type[1].strip()
+
+ f.write("[" + objs[1:].strip() + "], [" + types[1:].strip() + "])")
+
+ if (elm.startswith(":action")):
+ f.write("\n operator (")
+ lines = elm.split(":")
+ action_name = lines[1].split(" ")[1]
+ f.write(action_name + ",")
+ for line in lines[2:]:
+ if line.startswith("parameters"):
+ parameters = outermost_parentheses(line).split("?")[1:]
+ # print(parameters)
+ p = ""
+ for parameter in parameters:
+ obj_type = parameter.split("-")
+ p = p + ", (" + obj_type[0].strip() + "," + obj_type[1].strip() + " )"
+
+ p = p[1:]
+ f.write("args = [" + p.strip() + "],")
+ # print("args = [" + p.strip() + "],")
+
+ if line.startswith("precondition"):
+ f.write("preconditions = [")
+ precondition = list(parenthetic_contents(line))
+ for (l, pre) in precondition:
+ precon = ""
+ if l == 1:
+ # (player-at ?target)
+ condition = pre.split(" ")
+ f.write("condition(" + condition[0].strip())
+ for c in condition[1:]:
+ precon = precon + ", " + c.strip()
+
+ f.write(" [" + precon[1:].strip() + "]),\n")
+ f.write("],")
+ if line.startswith("effect"):
+ f.write("results=[")
+ effect = list(parenthetic_contents(line))
+ for (l, pre) in effect:
+ precon = ""
+ if l == 1:
+ # (player-at ?target)
+ condition = pre.split(" ")
+ f.write("condition(" + condition[0].strip() + ",")
+ for c in condition[1:]:
+ precon = precon + ", " + c.strip()
+
+ f.write(" [" + precon[1:].strip() + "]),\n")
+ f.write("])")
+
+
+# Function for creating __init__.py files at the specified directory
+def create_init(location):
+ # create an empty __init__.py file at the specified directory
+ f = open(location + "/__init__.py", "w")
+
+
+# Function regex replaces "" within the file specified with the new domain name
+def regex_filename(filename):
+ file = fileinput.FileInput(filename, inplace=True)
+
+ for line in file:
+ print(line.replace('', newDomainName), end='')
+
+ file.close()
+
+
+if __name__ == "__main__":
+ # manage args
+ parser = argparse.ArgumentParser()
+ parser.add_argument("domain", help="name of new domain")
+ parser.add_argument("pddl", help="name of .pddl file to create domain with")
+
+ # get and validate args
+ args = parser.parse_args()
+ newDomainName = args.domain
+ pddl_file = args.pddl
+ if not pddl_file.endswith('.pddl'): # ensure pddl_file name includes '.pddl'
+ pddl_file = pddl_file + '.pddl'
+
+
+ newDirectoryRoot = thisDir + "/" + newDomainName
+
+ # create desired directory structure
+ if not os.path.exists(newDirectoryRoot):
+ os.makedirs(newDirectoryRoot) # create the new domain directory
+
+ if not os.path.exists(newDirectoryRoot + "/plan"):
+ os.makedirs(newDirectoryRoot + "/plan") # create the new plan sub-directory
+
+ if not os.path.exists(newDirectoryRoot + "/problems"):
+ os.makedirs(newDirectoryRoot + "/problems") # create the new problems sub-directory
+
+ create_init(newDirectoryRoot) # create the empty __init__.py file needed in the new domain directory
+
+ # TODO: pass the .ppdl filename to the function to open the correct one
+ PDDL_to_MIDCA_DOMAIN(pddl_file, newDirectoryRoot + "/" + newDomainName + ".sim")
diff --git a/midca/domains/blocksworld/domains/arsonist.sim b/midca/domains/blocksworld/arsonist.sim
similarity index 100%
rename from midca/domains/blocksworld/domains/arsonist.sim
rename to midca/domains/blocksworld/arsonist.sim
diff --git a/midca/domains/blocksworld/domains/arsonist_extinguish.sim b/midca/domains/blocksworld/arsonist_extinguish.sim
similarity index 100%
rename from midca/domains/blocksworld/domains/arsonist_extinguish.sim
rename to midca/domains/blocksworld/arsonist_extinguish.sim
diff --git a/midca/domains/blocksworld/domains/arsonist_mortar.sim b/midca/domains/blocksworld/arsonist_mortar.sim
similarity index 100%
rename from midca/domains/blocksworld/domains/arsonist_mortar.sim
rename to midca/domains/blocksworld/arsonist_mortar.sim
diff --git a/midca/domains/blocksworld/domains/blocksworld.sim b/midca/domains/blocksworld/blocksworld.sim
similarity index 100%
rename from midca/domains/blocksworld/domains/blocksworld.sim
rename to midca/domains/blocksworld/blocksworld.sim
diff --git a/midca/domains/blocksworld/domains/sample_domain.sim b/midca/domains/blocksworld/sample_domain.sim
similarity index 100%
rename from midca/domains/blocksworld/domains/sample_domain.sim
rename to midca/domains/blocksworld/sample_domain.sim
diff --git a/midca/domains/coloredBlocksworld/coloredBlocksworld.cfg b/midca/domains/coloredBlocksworld/coloredBlocksworld.cfg
new file mode 100644
index 00000000..aa74a97c
--- /dev/null
+++ b/midca/domains/coloredBlocksworld/coloredBlocksworld.cfg
@@ -0,0 +1,16 @@
+middleware,ROS
+type,block,entity
+attribute,block,color
+attribute,block,x
+attribute,block,y
+attribute,block,z
+attributeValue,color,red,green,blue
+attributeValue,x,INT
+attributeValue,y,INT
+attributeValue,z,INT
+relation,on,block,block
+relation,clear,block
+action,pickup,loc
+action,putdown,loc
+action,stack,raise
+action,unstack,loc
\ No newline at end of file
diff --git a/midca/domains/coloredBlocksworld/ros/coloredBlocksworldDetectors.cpp b/midca/domains/coloredBlocksworld/ros/coloredBlocksworldDetectors.cpp
new file mode 100644
index 00000000..25dd0927
--- /dev/null
+++ b/midca/domains/coloredBlocksworld/ros/coloredBlocksworldDetectors.cpp
@@ -0,0 +1,40 @@
+/*********************************************************************
+ *
+ *
+ * For example, consider using PointCloudLab
+ * (https://github.com/COLAB2/baxter_pcl/blob/master/src/detect_objects.cpp)
+ *
+ *
+ *********************************************************************/
+
+#include
+
+
+std::string detect_block()
+{
+ //TODO: create block_attr string with the following attributes:
+ //['color', 'z', 'y', 'x']
+
+ return block_attr;
+}
+
+
+int main(int argc, char** argv)
+{
+ ROS_INFO_STREAM("Starting ../domains/coloredBlocksworld/ros/coloredBlocksworld Entity Detectors node");
+
+ ros::init(argc, argv, "../domains/coloredBlocksworld/ros/coloredBlocksworld_entity_detectors");
+ ros::NodeHandle n;
+
+ ros::Publisher block_pub = n.advertise("block_attr", 1);
+
+ while (ros::ok())
+ {
+ block_pub.publish(block_attr);
+
+ ros::spinOnce();
+ }
+
+ ros::spin();
+ return 0;
+}
\ No newline at end of file
diff --git a/midca/domains/coloredBlocksworld/ros/coloredBlocksworldEntitiesHandler.py b/midca/domains/coloredBlocksworld/ros/coloredBlocksworldEntitiesHandler.py
new file mode 100644
index 00000000..b0c3739f
--- /dev/null
+++ b/midca/domains/coloredBlocksworld/ros/coloredBlocksworldEntitiesHandler.py
@@ -0,0 +1,32 @@
+# https://github.com/COLAB2/midca/blob/c3e4cc9fab5683f44435816d90a7a2eb591c4ce4/midca/rosrun.py
+
+class coloredBlocksworldEntitiesHandler(IncomingMsgHandler):
+
+ '''
+ class that receives Point messages, where each message indicates that the given object
+ has been identified at that location. Args include the topic to listen to, object id,
+ and midca object to whose memory observations will be stored. Optionally the memory
+ key to be stored to can also be specified.
+ '''
+
+ def __init__(self, topic, midcaObject, memKey = None, history = None):
+ callback = lambda strMsg: self.store(strMsg)
+ msgType = String
+ self.left = None
+ super(coloredBlocksworldEntitiesHandler, self).__init__(topic, msgType, callback, midcaObject)
+ #self.objID = objID
+ if memKey:
+ self.memKey = memKey
+ else:
+ self.memKey = self.mem.ROS_OBJS_DETECTED
+ if history:
+ self.history = history
+ else:
+ self.history = self.mem.STATE_HISTORY
+
+ def store(self, data):
+ if not self.mem:
+ rospy.logerr("Trying to store data to a nonexistent MIDCA object.")
+
+ #TODO: Code should handle detecting the following relations (predicates):
+ #block: ['on', 'clear']
diff --git a/midca/domains/coloredBlocksworld/ros/coloredBlocksworld_async.py b/midca/domains/coloredBlocksworld/ros/coloredBlocksworld_async.py
new file mode 100644
index 00000000..daf9612f
--- /dev/null
+++ b/midca/domains/coloredBlocksworld/ros/coloredBlocksworld_async.py
@@ -0,0 +1,503 @@
+from midca import rosrun, plans
+from midca import midcatime
+import traceback
+from midca.examples.homography import *
+import math
+import copy
+import numpy as np
+
+
+try:
+ from geometry_msgs.msg import PointStamped
+ from geometry_msgs.msg import Point
+ from midca.examples import ObjectDetector
+ from std_msgs.msg import String
+ from scipy.spatial import distance
+except:
+ pass #if ROS is not installed, an error message will already have been generated.
+
+
+END_COLOR_CODE = '\033[0m'
+NOT_STARTED = 0
+NS_COLOR_CODE = END_COLOR_CODE
+IN_PROGRESS = 1
+IP_COLOR_CODE = '\033[92m'
+COMPLETE = 2
+C_COLOR_CODE = '\033[94m'
+FAILED = 3
+F_COLOR_CODE = '\033[91m'
+FEEDBACK_KEY = "code"
+CMD_ID_KEY = "cmd_id"
+
+LOC_TOPIC = "loc"
+RAISE_TOPIC = "raise"
+
+#set this to change output for all asynch actions.
+verbose = 2
+
+MAX_SIGHTING_LAG = 3.0
+MAX_SIGHTING_WAIT = 5.0
+
+def allowed_sighting_lag(objectID):
+ '''
+ returns how long ago an object can have been seen before MIDCA stops considering its
+ location known
+ '''
+ return MAX_SIGHTING_LAG
+
+def allowed_sighting_wait(objectID):
+ '''
+ returns the amount of midcatime MIDCA should wait to see an object before giving up.
+ '''
+ return MAX_SIGHTING_WAIT
+
+'''
+'''
+
+def get_asynch_action(midcaAction):
+ raise ArgumentException("midca action " + str(midcaAction) + " does not translate to a \
+ valid asynchronous action.")
+
+def asynch_plan(mem, midcaPlan):
+ '''
+ returns an asynchronous plan that corresponds to the given MIDCA plan.
+ '''
+ actions = []
+ goals = midcaPlan.goals
+ for midcaAction in midcaPlan.actions:
+ if midcaAction[0] == "block_until_seen":
+ actions.append(AwaitCurrentLocation(mem, midcaAction, midcaAction[1],
+ allowed_sighting_lag(midcaAction[1]), allowed_sighting_wait(midcaAction[1])))
+ elif midcaAction[0] == "unstack":
+ cmdID = rosrun.next_id()
+ actions.append(unstack(mem, midcaAction, midcaAction[1],
+ allowed_sighting_lag(midcaAction[1]), allowed_sighting_wait(midcaAction[1]),
+ ['loc'], cmdID))
+ elif midcaAction[0] == "pickup":
+ cmdID = rosrun.next_id()
+ actions.append(pickup(mem, midcaAction, midcaAction[1],
+ allowed_sighting_lag(midcaAction[1]), allowed_sighting_wait(midcaAction[1]),
+ ['loc'], cmdID))
+ elif midcaAction[0] == "putdown":
+ cmdID = rosrun.next_id()
+ actions.append(putdown(mem, midcaAction, midcaAction[1],
+ allowed_sighting_lag(midcaAction[1]), allowed_sighting_wait(midcaAction[1]),
+ ['loc'], cmdID))
+ elif midcaAction[0] == "stack":
+ cmdID = rosrun.next_id()
+ actions.append(stack(mem, midcaAction, midcaAction[1],
+ allowed_sighting_lag(midcaAction[1]), allowed_sighting_wait(midcaAction[1]),
+ ['raise'], cmdID))
+ else:
+ if verbose >= 1:
+ print "MIDCA action", midcaAction, "does not correspond to an asynch",
+ "action. MIDCA will skip this action"
+ return AsynchPlan(actions, goals)
+
+
+class AsynchPlan(plans.Plan):
+
+ '''
+ subclass of MIDCA Plan class that uses asynchronous actions.
+ '''
+
+ def finished(self):
+ '''
+ overrides plan.finished(). Declares a plan complete if all its actions report
+ complete or failed.
+ '''
+ for action in self.actions:
+ if action.status != COMPLETE and action.status != FAILED:
+ return False
+ return True
+
+ @property
+ def status(self):
+ '''
+ property that returns the plan's status. This can be NOT_STARTED, IN_PROGRESS,
+ FAILED, or COMPLETE. If any action fails, the plan is considered to have failed.
+ The plan is complete when all actions are complete.
+ '''
+ status = COMPLETE
+ for action in self.actions:
+ if action.status == FAILED:
+ return FAILED
+ elif action.status == NOT_STARTED and status == COMPLETE:
+ status = NOT_STARTED
+ elif action.status == IN_PROGRESS:
+ status = IN_PROGRESS
+ return status
+
+ def __str__(self):
+ s = ""
+ for action in self.actions:
+ if action.status == NOT_STARTED:
+ s += NS_COLOR_CODE
+ elif action.status == IN_PROGRESS:
+ s += IP_COLOR_CODE
+ elif action.status == FAILED:
+ s += F_COLOR_CODE
+ elif action.status == COMPLETE:
+ s += C_COLOR_CODE
+
+ s += str(action) + " "
+ return s[:-1] + END_COLOR_CODE
+
+class AsynchAction:
+
+ nextID = 0
+
+ def __init__(self, mem, midcaAction, executeFunc, isComplete, blocks):
+ self.status = NOT_STARTED
+ self.mem = mem
+ self.midcaAction = midcaAction
+ self.executeFunc = executeFunc
+ self.isComplete = isComplete
+ self.blocks = blocks
+ self.startTime = None
+ self.id = AsynchAction.nextID
+ AsynchAction.nextID += 1
+
+ def execute(self):
+ if not self.startTime:
+ self.startTime = midcatime.now()
+ self.status = IN_PROGRESS
+ if not self.executeFunc:
+ return
+ try:
+ self.executeFunc(self.mem, self.midcaAction, self.status)
+ except:
+ if verbose >= 2:
+ print "Error executing action", self, ":\n", traceback.format_exc(),
+ "\n\nAction assumed to be failed"
+ self.status = FAILED
+
+ def check_complete(self):
+ if not self.startTime:
+ self.startTime = midcatime.now()
+ if not self.check_complete:
+ return
+ try:
+ complete = self.isComplete(self.mem, self.midcaAction, self.status)
+ if verbose >= 2 and not complete:
+ print "Action", self, "not complete."
+ if verbose >= 1 and complete:
+ print "Action", self, "complete."
+ if complete:
+ self.status = COMPLETE
+ return complete
+ except:
+ if verbose >= 1:
+ print "Error checking completion status for action", self, " - Assuming \
+ failure:\n", traceback.format_exc()
+ self.status = FAILED
+
+ def ros_msg(self, topic, d):
+ '''
+ arg d should be a dictionary that contains the key/value pairs to be sent.
+ '''
+ sent = rosrun.send_msg(topic, rosrun.dict_as_msg)
+ if not sent:
+ if verbose >= 1:
+ print "Unable to send msg; ", d, "on topic", topic, " Action", self,
+ "assumed failed."
+ self.status = FAILED
+
+ def __str__(self):
+ return str(self.midcaAction)
+
+def get_last_position(mem, objectOrID):
+ state = mem.get(mem.STATE)
+ positions = state.all_pos(objectOrID)
+ if not positions:
+ return None
+ else:
+ for state_pos in reversed(positions):
+ if state_pos.position:
+ return (state_pos.position)
+ return None
+
+def get_last_location(mem, objectOrID):
+ world = mem.get(mem.STATE)
+ sightings = world.all_sightings(objectOrID)
+ if not sightings:
+ return None
+ else:
+ for detectionEvent in reversed(sightings):
+ if detectionEvent.loc:
+ return (detectionEvent.loc, detectionEvent.time)
+ return None
+
+
+
+
+class AwaitCurrentLocation(AsynchAction):
+
+ '''
+ Action that blocks until there is a current (within last maxAllowedLag seconds)
+ observation of the object's location.
+ '''
+
+ def __init__(self, mem, midcaAction, objectOrID, maxAllowedLag, maxDuration):
+ self.objectOrID = objectOrID
+ self.maxAllowedLag = maxAllowedLag
+ self.maxDuration = maxDuration
+ executeAction = None
+ completionCheck = lambda mem, midcaAction, status: self.completion_check()
+ AsynchAction.__init__(self, mem, midcaAction, executeAction,
+ completionCheck, True)
+
+ def completion_check(self):
+ t = midcatime.now()
+ if t - self.startTime > self.maxDuration:
+ if verbose >= 1:
+ print "max midcatime exceeded for action:", self, "- changing status to failed."
+ self.status = FAILED
+ return False
+ lastLocReport = get_last_location(self.mem, self.objectOrID)
+ if not lastLocReport:
+ return False
+ return t - lastLocReport[1] <= self.maxAllowedLag
+
+
+class unstack(AsynchAction):
+
+ def __init__(self, mem, midcaAction, objectOrID, maxAllowedLag, maxDuration, topics,
+ msgID):
+ self.objectOrID = objectOrID
+ self.maxAllowedLag = maxAllowedLag
+ self.maxDuration = maxDuration
+ self.lastCheck = 0.0
+ self.topics = topics
+ self.complete = False
+ self.msgID = msgID
+ # TODO: fill in formats for each topic
+ # Reference {'x': x, 'y': y, 'z': z, 'time': self.startTime, 'cmd_id': self.msgID}
+ self.topicFormats = {'loc': {},}
+
+ executeAction = lambda mem, midcaAction, status: self.send_point()
+ completionCheck = lambda mem, midcaAction, status: self.check_confirmation()
+ AsynchAction.__init__(self, mem, midcaAction, executeAction,
+ completionCheck, True)
+
+
+
+ def send_topic(self):
+
+ for topic in self.topics:
+ # Handle
+ self.msgDict = topicFormats[topic]
+
+ print self.msgDict
+
+ print "trying to send"
+ print topic
+
+ sent = rosrun.send_msg(topic, rosrun.dict_as_msg(self.msgDict))
+ if not sent:
+ if verbose >= 1:
+ print "Fail"
+ self.status = FAILED
+
+ def check_confirmation(self):
+ checkTime = self.lastCheck
+ self.lastCheck = midcatime.now()
+ feedback = self.mem.get(self.mem.FEEDBACK)
+ if not feedback:
+ return False
+ for item in reversed(feedback):
+ #if all items have been checked, either in this check or previous, return
+ if item['received_at'] - checkTime < 0:
+ return False
+ #else see if item is a completion or failure message with id == self.msgID
+ if item[CMD_ID_KEY] == self.msgID:
+ if item[FEEDBACK_KEY] == COMPLETE:
+ return True
+ elif item[FEEDBACK_KEY] == FAILED:
+ self.status = FAILED
+ if verbose >= 1:
+ print "MIDCA received feedback that action", self, "has failed"
+ return False
+ return False
+
+class pickup(AsynchAction):
+
+ def __init__(self, mem, midcaAction, objectOrID, maxAllowedLag, maxDuration, topics,
+ msgID):
+ self.objectOrID = objectOrID
+ self.maxAllowedLag = maxAllowedLag
+ self.maxDuration = maxDuration
+ self.lastCheck = 0.0
+ self.topics = topics
+ self.complete = False
+ self.msgID = msgID
+ # TODO: fill in formats for each topic
+ # Reference {'x': x, 'y': y, 'z': z, 'time': self.startTime, 'cmd_id': self.msgID}
+ self.topicFormats = {'loc': {},}
+
+ executeAction = lambda mem, midcaAction, status: self.send_point()
+ completionCheck = lambda mem, midcaAction, status: self.check_confirmation()
+ AsynchAction.__init__(self, mem, midcaAction, executeAction,
+ completionCheck, True)
+
+
+
+ def send_topic(self):
+
+ for topic in self.topics:
+ # Handle
+ self.msgDict = topicFormats[topic]
+
+ print self.msgDict
+
+ print "trying to send"
+ print topic
+
+ sent = rosrun.send_msg(topic, rosrun.dict_as_msg(self.msgDict))
+ if not sent:
+ if verbose >= 1:
+ print "Fail"
+ self.status = FAILED
+
+ def check_confirmation(self):
+ checkTime = self.lastCheck
+ self.lastCheck = midcatime.now()
+ feedback = self.mem.get(self.mem.FEEDBACK)
+ if not feedback:
+ return False
+ for item in reversed(feedback):
+ #if all items have been checked, either in this check or previous, return
+ if item['received_at'] - checkTime < 0:
+ return False
+ #else see if item is a completion or failure message with id == self.msgID
+ if item[CMD_ID_KEY] == self.msgID:
+ if item[FEEDBACK_KEY] == COMPLETE:
+ return True
+ elif item[FEEDBACK_KEY] == FAILED:
+ self.status = FAILED
+ if verbose >= 1:
+ print "MIDCA received feedback that action", self, "has failed"
+ return False
+ return False
+
+class putdown(AsynchAction):
+
+ def __init__(self, mem, midcaAction, objectOrID, maxAllowedLag, maxDuration, topics,
+ msgID):
+ self.objectOrID = objectOrID
+ self.maxAllowedLag = maxAllowedLag
+ self.maxDuration = maxDuration
+ self.lastCheck = 0.0
+ self.topics = topics
+ self.complete = False
+ self.msgID = msgID
+ # TODO: fill in formats for each topic
+ # Reference {'x': x, 'y': y, 'z': z, 'time': self.startTime, 'cmd_id': self.msgID}
+ self.topicFormats = {'loc': {},}
+
+ executeAction = lambda mem, midcaAction, status: self.send_point()
+ completionCheck = lambda mem, midcaAction, status: self.check_confirmation()
+ AsynchAction.__init__(self, mem, midcaAction, executeAction,
+ completionCheck, True)
+
+
+
+ def send_topic(self):
+
+ for topic in self.topics:
+ # Handle
+ self.msgDict = topicFormats[topic]
+
+ print self.msgDict
+
+ print "trying to send"
+ print topic
+
+ sent = rosrun.send_msg(topic, rosrun.dict_as_msg(self.msgDict))
+ if not sent:
+ if verbose >= 1:
+ print "Fail"
+ self.status = FAILED
+
+ def check_confirmation(self):
+ checkTime = self.lastCheck
+ self.lastCheck = midcatime.now()
+ feedback = self.mem.get(self.mem.FEEDBACK)
+ if not feedback:
+ return False
+ for item in reversed(feedback):
+ #if all items have been checked, either in this check or previous, return
+ if item['received_at'] - checkTime < 0:
+ return False
+ #else see if item is a completion or failure message with id == self.msgID
+ if item[CMD_ID_KEY] == self.msgID:
+ if item[FEEDBACK_KEY] == COMPLETE:
+ return True
+ elif item[FEEDBACK_KEY] == FAILED:
+ self.status = FAILED
+ if verbose >= 1:
+ print "MIDCA received feedback that action", self, "has failed"
+ return False
+ return False
+
+class stack(AsynchAction):
+
+ def __init__(self, mem, midcaAction, objectOrID, maxAllowedLag, maxDuration, topics,
+ msgID):
+ self.objectOrID = objectOrID
+ self.maxAllowedLag = maxAllowedLag
+ self.maxDuration = maxDuration
+ self.lastCheck = 0.0
+ self.topics = topics
+ self.complete = False
+ self.msgID = msgID
+ # TODO: fill in formats for each topic
+ # Reference {'x': x, 'y': y, 'z': z, 'time': self.startTime, 'cmd_id': self.msgID}
+ self.topicFormats = {'raise': {},}
+
+ executeAction = lambda mem, midcaAction, status: self.send_point()
+ completionCheck = lambda mem, midcaAction, status: self.check_confirmation()
+ AsynchAction.__init__(self, mem, midcaAction, executeAction,
+ completionCheck, True)
+
+
+
+ def send_topic(self):
+
+ for topic in self.topics:
+ # Handle
+ self.msgDict = topicFormats[topic]
+
+ print self.msgDict
+
+ print "trying to send"
+ print topic
+
+ sent = rosrun.send_msg(topic, rosrun.dict_as_msg(self.msgDict))
+ if not sent:
+ if verbose >= 1:
+ print "Fail"
+ self.status = FAILED
+
+ def check_confirmation(self):
+ checkTime = self.lastCheck
+ self.lastCheck = midcatime.now()
+ feedback = self.mem.get(self.mem.FEEDBACK)
+ if not feedback:
+ return False
+ for item in reversed(feedback):
+ #if all items have been checked, either in this check or previous, return
+ if item['received_at'] - checkTime < 0:
+ return False
+ #else see if item is a completion or failure message with id == self.msgID
+ if item[CMD_ID_KEY] == self.msgID:
+ if item[FEEDBACK_KEY] == COMPLETE:
+ return True
+ elif item[FEEDBACK_KEY] == FAILED:
+ self.status = FAILED
+ if verbose >= 1:
+ print "MIDCA received feedback that action", self, "has failed"
+ return False
+ return False
+
+
diff --git a/midca/domains/construction_domain/domains/arsonist_mortar_construction.sim b/midca/domains/construction_domain/arsonist_mortar_construction.sim
similarity index 100%
rename from midca/domains/construction_domain/domains/arsonist_mortar_construction.sim
rename to midca/domains/construction_domain/arsonist_mortar_construction.sim
diff --git a/midca/domains/construction_domain/domains/arsonist_mortar_hierarchy.sim b/midca/domains/construction_domain/arsonist_mortar_hierarchy.sim
similarity index 100%
rename from midca/domains/construction_domain/domains/arsonist_mortar_hierarchy.sim
rename to midca/domains/construction_domain/arsonist_mortar_hierarchy.sim
diff --git a/midca/domains/construction_domain/domains/restaurants.sim b/midca/domains/construction_domain/restaurants.sim
similarity index 100%
rename from midca/domains/construction_domain/domains/restaurants.sim
rename to midca/domains/construction_domain/restaurants.sim
diff --git a/midca/domains/jshop_domains/blocks_world/bw_ran_problems_5.shp b/midca/domains/jshop_domains/blocks_world/bw_ran_problems_5.shp
index 2b03f9ae..770fe5c1 100644
--- a/midca/domains/jshop_domains/blocks_world/bw_ran_problems_5.shp
+++ b/midca/domains/jshop_domains/blocks_world/bw_ran_problems_5.shp
@@ -1,12 +1,10 @@
(defproblem bw-ran-5-1 blocks-normal ((arm-empty)
(clear d)
-(on-table a)
(on-table c)
(on b a)
(on d b)
(clear c)
+(on-table a)
)
((achieve-goals ( list
-(on c b)
- ))))
\ No newline at end of file
diff --git a/midca/domains/logistics/domains/domain.sim b/midca/domains/logistics/domain.sim
similarity index 100%
rename from midca/domains/logistics/domains/domain.sim
rename to midca/domains/logistics/domain.sim
diff --git a/midca/domains/logistics/domains/domain2.sim b/midca/domains/logistics/domain2.sim
similarity index 100%
rename from midca/domains/logistics/domains/domain2.sim
rename to midca/domains/logistics/domain2.sim
diff --git a/midca/domains/minecraft/__init__.py b/midca/domains/minecraft/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/midca/domains/minecraft/minecraft.cfg b/midca/domains/minecraft/minecraft.cfg
new file mode 100644
index 00000000..2b0406a8
--- /dev/null
+++ b/midca/domains/minecraft/minecraft.cfg
@@ -0,0 +1,33 @@
+middleware,mOOSE
+type,mob,entity
+type,item,entity
+type,block,item
+type,tool,item
+type,stone,block
+type,grass,block
+type,pickaxe,tool
+type,sword,tool
+type,player,mob
+type,hostile,mob
+type,passive,mob
+type,creeper,hostile
+type,skeleton,hostile
+type,pig,passive
+type,chicken,passive
+attribute,mob,health
+attribute,passive,age
+attribute,block,breakable
+attribute,item,craftable
+attribute,sword,damage
+attribute,pickaxe,speed
+attribute,player,armor
+attribute,skeleton,armor
+relation,place,block
+relation,kill,mob,mob
+relation,break,block
+relation,use,tool
+action,breakBlock,aim,swing,pickup
+action,placeBlock,aim,swing
+action,useBlock,aim,swing
+action,drinkPotion,swing,potion
+action,eat,swing,food
\ No newline at end of file
diff --git a/midca/domains/minecraft/minecraft.sim b/midca/domains/minecraft/minecraft.sim
new file mode 100644
index 00000000..2a11f253
--- /dev/null
+++ b/midca/domains/minecraft/minecraft.sim
@@ -0,0 +1,87 @@
+type(resource)
+type(mapgrid)
+type(player)
+type(resource)
+type(material)
+type(tool)
+type(craftgrid)
+type(mapgrid)
+type(direction)
+type(player)
+type(monster)
+type(weapon)
+type(food)
+type(potion)
+type(Helmet)
+type(chestplates)
+
+ predicate(is-trap,[loc], [mapgrid])
+ predicate(looking-for,[res], [resource])
+ predicate(know-where,[res,loc], [resource,mapgrid])
+ predicate(player-at,[loc], [mapgrid])
+ predicate(in-shelter,[], [])
+ predicate(look-at,[direction], [direction])
+ predicate(monster-at,[zombie,loc], [monster,mapgrid])
+ predicate(thing-at-map,[obj,loc], [resource,mapgrid])
+ predicate(thing-at-loc,[obj,loc], [resource,mapgrid])
+ predicate(known-loc,[obj], [resource])
+ predicate(placed-thing-at-map,[obj,loc], [material,mapgrid])
+ predicate(resource-at-craft,[res,loc], [thing,craftgrid])
+ predicate(craft-empty,[loc], [craftgrid])
+ predicate(connect,[from,to], [mapgrid,mapgrid])
+ predicate(next-to,[from,to], [direction,direction])
+ predicate(crafting,[], [])
+ predicate(survive,[], [])
+ predicate(eat,[food], [food])
+ predicate(is-attacked,[], [])
+ predicate(is-trapped,[], [])
+ predicate(is-dead,[player], [player])
+ predicate(is-alive,[player], [player])
+ predicate(head-armed,[], [])
+ predicate(chest-armed,[], [])
+ operator (move
+,args = [(from,mapgrid ), (to,mapgrid )],preconditions = [condition(player-at [?from]),
+condition(connect [?from, ?to]),
+],results=[condition(player-at, [?to]),
+condition(not, [(player-at, ?from)]),
+])
+ operator (,args = [(loc1,mapgrid ), (loc,mapgrid )],preconditions = [condition(player-at [?loc1]),
+condition(connect [?loc1, ?loc]),
+condition(thing-at-loc [arrow_trap, ?loc]),
+condition(not [(is-trapped)]),
+condition(neq [(player-current-health), 0]),
+],results=[condition(decrease, [(player-current-health), 5]),
+condition(thing-at-map, [arrow, ?loc1]),
+condition(is-trapped, []),
+])
+ operator (event-skeleton-attacked
+,args = [(loc1,mapgrid ), (loc,mapgrid )],preconditions = [condition(player-at [?loc1]),
+condition(connect [?loc1, ?loc]),
+condition(thing-at-loc [skeleton, ?loc]),
+condition(not [(is-attacked)]),
+condition(neq [(player-current-health), 0]),
+],results=[condition(decrease, [(player-current-health), 5]),
+condition(thing-at-map, [arrow, ?loc1]),
+condition(is-attacked, []),
+])
+ operator (event-monster-explosion
+,args = [(loc1,mapgrid ), (loc,mapgrid )],preconditions = [condition(player-at [?loc1]),
+condition(connect [?loc1, ?loc]),
+condition(thing-at-loc [monster, ?loc]),
+condition(not [(is-attacked)]),
+condition(neq [(player-current-health), 0]),
+],results=[condition(decrease, [(player-current-health), 5]),
+condition(thing-at-map, [monster-remains, ?loc1]),
+condition(is-attacked, []),
+])
+ operator (event-die
+,args = [(player,player )],preconditions = [condition(is-alive [?player]),
+condition(eq [(player-current-health), 0]),
+],results=[condition(is-dead, [?player]),
+])
+ operator (event-find
+ ,args = [(res,resource ), (loc,mapgrid ), (player,loc )],preconditions = [condition(looking-for [?res]),
+condition(connected [?loc, ?player-loc]),
+condition(thing-at-loc [?res, ?loc]),
+],results=[condition(know-where, [?res, ?loc]),
+])
\ No newline at end of file
diff --git a/midca/domains/minecraft/plan/minecraft.pddl b/midca/domains/minecraft/plan/minecraft.pddl
new file mode 100644
index 00000000..d81a7ac9
--- /dev/null
+++ b/midca/domains/minecraft/plan/minecraft.pddl
@@ -0,0 +1,180 @@
+(define (domain minecraft-beta)
+ (:requirements :typing :fluents :existential-preconditions)
+ (:types
+ resource - thing
+ mapgrid
+ player
+ )
+
+ (:types
+ resource - thing
+ material - thing
+ tool - thing
+ craftgrid
+ mapgrid
+ direction
+ player
+ monster - thing
+ weapon - thing
+ food - thing
+ potion - thing
+ Helmet - Armor
+ chestplates - Armor
+ )
+
+ (:predicates
+ (is-trap ?loc - mapgrid)
+ (looking-for ?res - resource)
+ (know-where ?res - resource ?loc - mapgrid)
+ (player-at ?loc - mapgrid)
+ (in-shelter)
+ (look-at ?direction - direction)
+ (monster-at ?zombie - monster ?loc - mapgrid)
+ (thing-at-map ?obj - resource ?loc - mapgrid)
+ (thing-at-loc ?obj - resource ?loc - mapgrid)
+ (known-loc ?obj - resource)
+ (placed-thing-at-map ?obj - material ?loc - mapgrid)
+ (resource-at-craft ?res - thing ?loc - craftgrid)
+ (craft-empty ?loc - craftgrid)
+ (connect ?from - mapgrid ?to - mapgrid)
+ (next-to ?from - direction ?to - direction)
+ (crafting)
+ (survive)
+ (eat ?food - food)
+ (is-attacked)
+ (is-trapped)
+ (is-dead ?player -player)
+ (is-alive ?player -player)
+ (head-armed)
+ (chest-armed)
+ )
+ (:hidden is-trap thing-at-loc is-attacked is-trapped)
+
+ (:functions
+ (self) - player
+ (thing-available ?obj - thing) - int
+ (current-harvest-duration) - int
+ (current-harvest-location) - int
+ (duration-need ?tool - tool ?res - resource) - int
+ (location-id ?loc - mapgrid) - int
+ (tool-id ?tool - tool) - int
+ (tool-in-hand) - int
+ (tool-max-health ?tool - tool) - int
+ (tool-current-health ?tool - tool) - int
+ (player-current-health) - int
+ (furnace-fuel) - int
+ (current-hunger-value) - int
+ (food-value ?f -food) - int
+ )
+
+
+
+ ;; ----------------------------------------------------
+ (:action move
+ :parameters (?from - mapgrid ?to - mapgrid)
+ :precondition
+ (and
+ (player-at ?from)
+ (connect ?from ?to)
+
+ )
+ :effect
+ (and
+ (player-at ?to)
+ (not (player-at ?from))
+
+ )
+ )
+ ;;-----------------------------------------------------
+
+ (:action event-fall-in-trap
+ :parameters (?loc1 - mapgrid ?loc - mapgrid)
+ :precondition
+ ( and
+ (player-at ?loc1)
+ (connect ?loc1 ?loc)
+ (thing-at-loc arrow_trap ?loc)
+
+ (not (is-trapped))
+ (neq (player-current-health) 0)
+ )
+ :effect
+ (and
+ (decrease (player-current-health) 5)
+ (thing-at-map arrow ?loc1)
+ (is-trapped)
+ )
+ )
+ ;;------------------------------------------------------
+
+ (:action event-skeleton-attacked
+ :parameters (?loc1 - mapgrid ?loc - mapgrid)
+ :precondition
+ ( and
+ (player-at ?loc1)
+ (connect ?loc1 ?loc)
+ (thing-at-loc skeleton ?loc)
+ (not (is-attacked))
+ (neq (player-current-health) 0)
+ )
+ :effect
+ (and
+ (decrease (player-current-health) 5)
+ (thing-at-map arrow ?loc1)
+ (is-attacked)
+ )
+ )
+ ;;----------------------------------------------
+ (:action event-monster-explosion
+ :parameters (?loc1 - mapgrid ?loc - mapgrid)
+ :precondition
+ ( and
+ (player-at ?loc1)
+ (connect ?loc1 ?loc)
+ (thing-at-loc monster ?loc)
+ (not (is-attacked))
+ (neq (player-current-health) 0)
+
+ )
+ :effect
+ (and
+ (decrease (player-current-health) 5)
+ (thing-at-map monster-remains ?loc1)
+ (is-attacked)
+ )
+ )
+ ;;----------------------------------------------
+
+ (:action event-die
+ :parameters (?player -player)
+ :precondition
+ ( and
+ (is-alive ?player)
+ (eq (player-current-health) 0)
+ )
+ :effect
+ (and
+ (is-dead ?player)
+ )
+ )
+
+ ;;---------------------------------------------
+
+ (:action event-find
+ :parameters (?res -resource ?loc -mapgrid ?player-loc -mapgrid)
+ :precondition
+ (and
+ (looking-for ?res)
+ (connected ?loc ?player-loc)
+ (thing-at-loc ?res ?loc)
+ )
+ :effect
+ (and
+ (know-where ?res ?loc)
+ )
+
+
+ )
+
+
+)
\ No newline at end of file
diff --git a/midca/domains/minecraft/ros/minecraftDetectors.cpp b/midca/domains/minecraft/ros/minecraftDetectors.cpp
new file mode 100644
index 00000000..507134cf
--- /dev/null
+++ b/midca/domains/minecraft/ros/minecraftDetectors.cpp
@@ -0,0 +1,120 @@
+/*********************************************************************
+ *
+ *
+ * For example, consider using PointCloudLab
+ * (https://github.com/COLAB2/baxter_pcl/blob/master/src/detect_objects.cpp)
+ *
+ *
+ *********************************************************************/
+
+#include
+
+
+std::string detect_stone()
+{
+ //TODO: create stone_attr string with the following attributes:
+ //['craftable', 'breakable']
+
+ return stone_attr;
+}
+
+std::string detect_skeleton()
+{
+ //TODO: create skeleton_attr string with the following attributes:
+ //['health', 'armor']
+
+ return skeleton_attr;
+}
+
+std::string detect_creeper()
+{
+ //TODO: create creeper_attr string with the following attributes:
+ //['health']
+
+ return creeper_attr;
+}
+
+std::string detect_pig()
+{
+ //TODO: create pig_attr string with the following attributes:
+ //['health', 'age']
+
+ return pig_attr;
+}
+
+std::string detect_player()
+{
+ //TODO: create player_attr string with the following attributes:
+ //['health', 'armor']
+
+ return player_attr;
+}
+
+std::string detect_pickaxe()
+{
+ //TODO: create pickaxe_attr string with the following attributes:
+ //['craftable', 'speed']
+
+ return pickaxe_attr;
+}
+
+std::string detect_sword()
+{
+ //TODO: create sword_attr string with the following attributes:
+ //['craftable', 'damage']
+
+ return sword_attr;
+}
+
+std::string detect_chicken()
+{
+ //TODO: create chicken_attr string with the following attributes:
+ //['health', 'age']
+
+ return chicken_attr;
+}
+
+std::string detect_grass()
+{
+ //TODO: create grass_attr string with the following attributes:
+ //['craftable', 'breakable']
+
+ return grass_attr;
+}
+
+
+int main(int argc, char** argv)
+{
+ ROS_INFO_STREAM("Starting ../domains/minecraft/ros/minecraft Entity Detectors node");
+
+ ros::init(argc, argv, "../domains/minecraft/ros/minecraft_entity_detectors");
+ ros::NodeHandle n;
+
+ ros::Publisher stone_pub = n.advertise("stone_attr", 1);
+ ros::Publisher skeleton_pub = n.advertise("skeleton_attr", 1);
+ ros::Publisher creeper_pub = n.advertise("creeper_attr", 1);
+ ros::Publisher pig_pub = n.advertise("pig_attr", 1);
+ ros::Publisher player_pub = n.advertise("player_attr", 1);
+ ros::Publisher pickaxe_pub = n.advertise("pickaxe_attr", 1);
+ ros::Publisher sword_pub = n.advertise("sword_attr", 1);
+ ros::Publisher chicken_pub = n.advertise("chicken_attr", 1);
+ ros::Publisher grass_pub = n.advertise("grass_attr", 1);
+
+ while (ros::ok())
+ {
+ stone_pub.publish(stone_attr);
+ skeleton_pub.publish(skeleton_attr);
+ creeper_pub.publish(creeper_attr);
+ pig_pub.publish(pig_attr);
+ player_pub.publish(player_attr);
+ pickaxe_pub.publish(pickaxe_attr);
+ sword_pub.publish(sword_attr);
+ chicken_pub.publish(chicken_attr);
+ grass_pub.publish(grass_attr);
+
+ ros::spinOnce();
+ }
+
+ ros::spin();
+ return 0;
+}
\ No newline at end of file
diff --git a/midca/domains/minecraft/ros/minecraftEntitiesHandler.py b/midca/domains/minecraft/ros/minecraftEntitiesHandler.py
new file mode 100644
index 00000000..94c38d42
--- /dev/null
+++ b/midca/domains/minecraft/ros/minecraftEntitiesHandler.py
@@ -0,0 +1,40 @@
+# https://github.com/COLAB2/midca/blob/c3e4cc9fab5683f44435816d90a7a2eb591c4ce4/midca/rosrun.py
+
+class minecraftEntitiesHandler(IncomingMsgHandler):
+
+ '''
+ class that receives Point messages, where each message indicates that the given object
+ has been identified at that location. Args include the topic to listen to, object id,
+ and midca object to whose memory observations will be stored. Optionally the memory
+ key to be stored to can also be specified.
+ '''
+
+ def __init__(self, topic, midcaObject, memKey = None, history = None):
+ callback = lambda strMsg: self.store(strMsg)
+ msgType = String
+ self.left = None
+ super(minecraftEntitiesHandler, self).__init__(topic, msgType, callback, midcaObject)
+ #self.objID = objID
+ if memKey:
+ self.memKey = memKey
+ else:
+ self.memKey = self.mem.ROS_OBJS_DETECTED
+ if history:
+ self.history = history
+ else:
+ self.history = self.mem.STATE_HISTORY
+
+ def store(self, data):
+ if not self.mem:
+ rospy.logerr("Trying to store data to a nonexistent MIDCA object.")
+
+ #TODO: Code should handle detecting the following relations (predicates):
+ #stone: ['place', 'break']
+ #skeleton: ['kill']
+ #creeper: ['kill']
+ #pig: ['kill']
+ #player: ['kill']
+ #pickaxe: ['use']
+ #sword: ['use']
+ #chicken: ['kill']
+ #grass: ['place', 'break']
diff --git a/midca/domains/minecraft/ros/minecraft_async.py b/midca/domains/minecraft/ros/minecraft_async.py
new file mode 100644
index 00000000..5fe2a13a
--- /dev/null
+++ b/midca/domains/minecraft/ros/minecraft_async.py
@@ -0,0 +1,571 @@
+from midca import rosrun, plans
+from midca import midcatime
+import traceback
+from midca.examples.homography import *
+import math
+import copy
+import numpy as np
+
+
+try:
+ from geometry_msgs.msg import PointStamped
+ from geometry_msgs.msg import Point
+ from midca.examples import ObjectDetector
+ from std_msgs.msg import String
+ from scipy.spatial import distance
+except:
+ pass #if ROS is not installed, an error message will already have been generated.
+
+
+END_COLOR_CODE = '\033[0m'
+NOT_STARTED = 0
+NS_COLOR_CODE = END_COLOR_CODE
+IN_PROGRESS = 1
+IP_COLOR_CODE = '\033[92m'
+COMPLETE = 2
+C_COLOR_CODE = '\033[94m'
+FAILED = 3
+F_COLOR_CODE = '\033[91m'
+FEEDBACK_KEY = "code"
+CMD_ID_KEY = "cmd_id"
+
+AIM_TOPIC = "aim"
+FOOD_TOPIC = "food"
+PICKUP_TOPIC = "pickup"
+POTION_TOPIC = "potion"
+SWING_TOPIC = "swing"
+
+#set this to change output for all asynch actions.
+verbose = 2
+
+MAX_SIGHTING_LAG = 3.0
+MAX_SIGHTING_WAIT = 5.0
+
+def allowed_sighting_lag(objectID):
+ '''
+ returns how long ago an object can have been seen before MIDCA stops considering its
+ location known
+ '''
+ return MAX_SIGHTING_LAG
+
+def allowed_sighting_wait(objectID):
+ '''
+ returns the amount of midcatime MIDCA should wait to see an object before giving up.
+ '''
+ return MAX_SIGHTING_WAIT
+
+'''
+'''
+
+def get_asynch_action(midcaAction):
+ raise ArgumentException("midca action " + str(midcaAction) + " does not translate to a \
+ valid asynchronous action.")
+
+def asynch_plan(mem, midcaPlan):
+ '''
+ returns an asynchronous plan that corresponds to the given MIDCA plan.
+ '''
+ actions = []
+ goals = midcaPlan.goals
+ for midcaAction in midcaPlan.actions:
+ if midcaAction[0] == "block_until_seen":
+ actions.append(AwaitCurrentLocation(mem, midcaAction, midcaAction[1],
+ allowed_sighting_lag(midcaAction[1]), allowed_sighting_wait(midcaAction[1])))
+ elif midcaAction[0] == "drinkPotion":
+ cmdID = rosrun.next_id()
+ actions.append(drinkPotion(mem, midcaAction, midcaAction[1],
+ allowed_sighting_lag(midcaAction[1]), allowed_sighting_wait(midcaAction[1]),
+ ['swing', 'potion'], cmdID))
+ elif midcaAction[0] == "breakBlock":
+ cmdID = rosrun.next_id()
+ actions.append(breakBlock(mem, midcaAction, midcaAction[1],
+ allowed_sighting_lag(midcaAction[1]), allowed_sighting_wait(midcaAction[1]),
+ ['aim', 'swing', 'pickup'], cmdID))
+ elif midcaAction[0] == "useBlock":
+ cmdID = rosrun.next_id()
+ actions.append(useBlock(mem, midcaAction, midcaAction[1],
+ allowed_sighting_lag(midcaAction[1]), allowed_sighting_wait(midcaAction[1]),
+ ['aim', 'swing'], cmdID))
+ elif midcaAction[0] == "eat":
+ cmdID = rosrun.next_id()
+ actions.append(eat(mem, midcaAction, midcaAction[1],
+ allowed_sighting_lag(midcaAction[1]), allowed_sighting_wait(midcaAction[1]),
+ ['swing', 'food'], cmdID))
+ elif midcaAction[0] == "placeBlock":
+ cmdID = rosrun.next_id()
+ actions.append(placeBlock(mem, midcaAction, midcaAction[1],
+ allowed_sighting_lag(midcaAction[1]), allowed_sighting_wait(midcaAction[1]),
+ ['aim', 'swing'], cmdID))
+ else:
+ if verbose >= 1:
+ print "MIDCA action", midcaAction, "does not correspond to an asynch",
+ "action. MIDCA will skip this action"
+ return AsynchPlan(actions, goals)
+
+
+class AsynchPlan(plans.Plan):
+
+ '''
+ subclass of MIDCA Plan class that uses asynchronous actions.
+ '''
+
+ def finished(self):
+ '''
+ overrides plan.finished(). Declares a plan complete if all its actions report
+ complete or failed.
+ '''
+ for action in self.actions:
+ if action.status != COMPLETE and action.status != FAILED:
+ return False
+ return True
+
+ @property
+ def status(self):
+ '''
+ property that returns the plan's status. This can be NOT_STARTED, IN_PROGRESS,
+ FAILED, or COMPLETE. If any action fails, the plan is considered to have failed.
+ The plan is complete when all actions are complete.
+ '''
+ status = COMPLETE
+ for action in self.actions:
+ if action.status == FAILED:
+ return FAILED
+ elif action.status == NOT_STARTED and status == COMPLETE:
+ status = NOT_STARTED
+ elif action.status == IN_PROGRESS:
+ status = IN_PROGRESS
+ return status
+
+ def __str__(self):
+ s = ""
+ for action in self.actions:
+ if action.status == NOT_STARTED:
+ s += NS_COLOR_CODE
+ elif action.status == IN_PROGRESS:
+ s += IP_COLOR_CODE
+ elif action.status == FAILED:
+ s += F_COLOR_CODE
+ elif action.status == COMPLETE:
+ s += C_COLOR_CODE
+
+ s += str(action) + " "
+ return s[:-1] + END_COLOR_CODE
+
+class AsynchAction:
+
+ nextID = 0
+
+ def __init__(self, mem, midcaAction, executeFunc, isComplete, blocks):
+ self.status = NOT_STARTED
+ self.mem = mem
+ self.midcaAction = midcaAction
+ self.executeFunc = executeFunc
+ self.isComplete = isComplete
+ self.blocks = blocks
+ self.startTime = None
+ self.id = AsynchAction.nextID
+ AsynchAction.nextID += 1
+
+ def execute(self):
+ if not self.startTime:
+ self.startTime = midcatime.now()
+ self.status = IN_PROGRESS
+ if not self.executeFunc:
+ return
+ try:
+ self.executeFunc(self.mem, self.midcaAction, self.status)
+ except:
+ if verbose >= 2:
+ print "Error executing action", self, ":\n", traceback.format_exc(),
+ "\n\nAction assumed to be failed"
+ self.status = FAILED
+
+ def check_complete(self):
+ if not self.startTime:
+ self.startTime = midcatime.now()
+ if not self.check_complete:
+ return
+ try:
+ complete = self.isComplete(self.mem, self.midcaAction, self.status)
+ if verbose >= 2 and not complete:
+ print "Action", self, "not complete."
+ if verbose >= 1 and complete:
+ print "Action", self, "complete."
+ if complete:
+ self.status = COMPLETE
+ return complete
+ except:
+ if verbose >= 1:
+ print "Error checking completion status for action", self, " - Assuming \
+ failure:\n", traceback.format_exc()
+ self.status = FAILED
+
+ def ros_msg(self, topic, d):
+ '''
+ arg d should be a dictionary that contains the key/value pairs to be sent.
+ '''
+ sent = rosrun.send_msg(topic, rosrun.dict_as_msg)
+ if not sent:
+ if verbose >= 1:
+ print "Unable to send msg; ", d, "on topic", topic, " Action", self,
+ "assumed failed."
+ self.status = FAILED
+
+ def __str__(self):
+ return str(self.midcaAction)
+
+def get_last_position(mem, objectOrID):
+ state = mem.get(mem.STATE)
+ positions = state.all_pos(objectOrID)
+ if not positions:
+ return None
+ else:
+ for state_pos in reversed(positions):
+ if state_pos.position:
+ return (state_pos.position)
+ return None
+
+def get_last_location(mem, objectOrID):
+ world = mem.get(mem.STATE)
+ sightings = world.all_sightings(objectOrID)
+ if not sightings:
+ return None
+ else:
+ for detectionEvent in reversed(sightings):
+ if detectionEvent.loc:
+ return (detectionEvent.loc, detectionEvent.time)
+ return None
+
+
+
+
+class AwaitCurrentLocation(AsynchAction):
+
+ '''
+ Action that blocks until there is a current (within last maxAllowedLag seconds)
+ observation of the object's location.
+ '''
+
+ def __init__(self, mem, midcaAction, objectOrID, maxAllowedLag, maxDuration):
+ self.objectOrID = objectOrID
+ self.maxAllowedLag = maxAllowedLag
+ self.maxDuration = maxDuration
+ executeAction = None
+ completionCheck = lambda mem, midcaAction, status: self.completion_check()
+ AsynchAction.__init__(self, mem, midcaAction, executeAction,
+ completionCheck, True)
+
+ def completion_check(self):
+ t = midcatime.now()
+ if t - self.startTime > self.maxDuration:
+ if verbose >= 1:
+ print "max midcatime exceeded for action:", self, "- changing status to failed."
+ self.status = FAILED
+ return False
+ lastLocReport = get_last_location(self.mem, self.objectOrID)
+ if not lastLocReport:
+ return False
+ return t - lastLocReport[1] <= self.maxAllowedLag
+
+
+class drinkPotion(AsynchAction):
+
+ def __init__(self, mem, midcaAction, objectOrID, maxAllowedLag, maxDuration, topics,
+ msgID):
+ self.objectOrID = objectOrID
+ self.maxAllowedLag = maxAllowedLag
+ self.maxDuration = maxDuration
+ self.lastCheck = 0.0
+ self.topics = topics
+ self.complete = False
+ self.msgID = msgID
+ # TODO: fill in formats for each topic
+ # Reference {'x': x, 'y': y, 'z': z, 'time': self.startTime, 'cmd_id': self.msgID}
+ self.topicFormats = {'swing': {},'potion': {},}
+
+ executeAction = lambda mem, midcaAction, status: self.send_point()
+ completionCheck = lambda mem, midcaAction, status: self.check_confirmation()
+ AsynchAction.__init__(self, mem, midcaAction, executeAction,
+ completionCheck, True)
+
+
+
+ def send_topic(self):
+
+ for topic in self.topics:
+ # Handle
+ self.msgDict = topicFormats[topic]
+
+ print self.msgDict
+
+ print "trying to send"
+ print topic
+
+ sent = rosrun.send_msg(topic, rosrun.dict_as_msg(self.msgDict))
+ if not sent:
+ if verbose >= 1:
+ print "Fail"
+ self.status = FAILED
+
+ def check_confirmation(self):
+ checkTime = self.lastCheck
+ self.lastCheck = midcatime.now()
+ feedback = self.mem.get(self.mem.FEEDBACK)
+ if not feedback:
+ return False
+ for item in reversed(feedback):
+ #if all items have been checked, either in this check or previous, return
+ if item['received_at'] - checkTime < 0:
+ return False
+ #else see if item is a completion or failure message with id == self.msgID
+ if item[CMD_ID_KEY] == self.msgID:
+ if item[FEEDBACK_KEY] == COMPLETE:
+ return True
+ elif item[FEEDBACK_KEY] == FAILED:
+ self.status = FAILED
+ if verbose >= 1:
+ print "MIDCA received feedback that action", self, "has failed"
+ return False
+ return False
+
+class breakBlock(AsynchAction):
+
+ def __init__(self, mem, midcaAction, objectOrID, maxAllowedLag, maxDuration, topics,
+ msgID):
+ self.objectOrID = objectOrID
+ self.maxAllowedLag = maxAllowedLag
+ self.maxDuration = maxDuration
+ self.lastCheck = 0.0
+ self.topics = topics
+ self.complete = False
+ self.msgID = msgID
+ # TODO: fill in formats for each topic
+ # Reference {'x': x, 'y': y, 'z': z, 'time': self.startTime, 'cmd_id': self.msgID}
+ self.topicFormats = {'aim': {},'swing': {},'pickup': {},}
+
+ executeAction = lambda mem, midcaAction, status: self.send_point()
+ completionCheck = lambda mem, midcaAction, status: self.check_confirmation()
+ AsynchAction.__init__(self, mem, midcaAction, executeAction,
+ completionCheck, True)
+
+
+
+ def send_topic(self):
+
+ for topic in self.topics:
+ # Handle
+ self.msgDict = topicFormats[topic]
+
+ print self.msgDict
+
+ print "trying to send"
+ print topic
+
+ sent = rosrun.send_msg(topic, rosrun.dict_as_msg(self.msgDict))
+ if not sent:
+ if verbose >= 1:
+ print "Fail"
+ self.status = FAILED
+
+ def check_confirmation(self):
+ checkTime = self.lastCheck
+ self.lastCheck = midcatime.now()
+ feedback = self.mem.get(self.mem.FEEDBACK)
+ if not feedback:
+ return False
+ for item in reversed(feedback):
+ #if all items have been checked, either in this check or previous, return
+ if item['received_at'] - checkTime < 0:
+ return False
+ #else see if item is a completion or failure message with id == self.msgID
+ if item[CMD_ID_KEY] == self.msgID:
+ if item[FEEDBACK_KEY] == COMPLETE:
+ return True
+ elif item[FEEDBACK_KEY] == FAILED:
+ self.status = FAILED
+ if verbose >= 1:
+ print "MIDCA received feedback that action", self, "has failed"
+ return False
+ return False
+
+class useBlock(AsynchAction):
+
+ def __init__(self, mem, midcaAction, objectOrID, maxAllowedLag, maxDuration, topics,
+ msgID):
+ self.objectOrID = objectOrID
+ self.maxAllowedLag = maxAllowedLag
+ self.maxDuration = maxDuration
+ self.lastCheck = 0.0
+ self.topics = topics
+ self.complete = False
+ self.msgID = msgID
+ # TODO: fill in formats for each topic
+ # Reference {'x': x, 'y': y, 'z': z, 'time': self.startTime, 'cmd_id': self.msgID}
+ self.topicFormats = {'aim': {},'swing': {},}
+
+ executeAction = lambda mem, midcaAction, status: self.send_point()
+ completionCheck = lambda mem, midcaAction, status: self.check_confirmation()
+ AsynchAction.__init__(self, mem, midcaAction, executeAction,
+ completionCheck, True)
+
+
+
+ def send_topic(self):
+
+ for topic in self.topics:
+ # Handle
+ self.msgDict = topicFormats[topic]
+
+ print self.msgDict
+
+ print "trying to send"
+ print topic
+
+ sent = rosrun.send_msg(topic, rosrun.dict_as_msg(self.msgDict))
+ if not sent:
+ if verbose >= 1:
+ print "Fail"
+ self.status = FAILED
+
+ def check_confirmation(self):
+ checkTime = self.lastCheck
+ self.lastCheck = midcatime.now()
+ feedback = self.mem.get(self.mem.FEEDBACK)
+ if not feedback:
+ return False
+ for item in reversed(feedback):
+ #if all items have been checked, either in this check or previous, return
+ if item['received_at'] - checkTime < 0:
+ return False
+ #else see if item is a completion or failure message with id == self.msgID
+ if item[CMD_ID_KEY] == self.msgID:
+ if item[FEEDBACK_KEY] == COMPLETE:
+ return True
+ elif item[FEEDBACK_KEY] == FAILED:
+ self.status = FAILED
+ if verbose >= 1:
+ print "MIDCA received feedback that action", self, "has failed"
+ return False
+ return False
+
+class eat(AsynchAction):
+
+ def __init__(self, mem, midcaAction, objectOrID, maxAllowedLag, maxDuration, topics,
+ msgID):
+ self.objectOrID = objectOrID
+ self.maxAllowedLag = maxAllowedLag
+ self.maxDuration = maxDuration
+ self.lastCheck = 0.0
+ self.topics = topics
+ self.complete = False
+ self.msgID = msgID
+ # TODO: fill in formats for each topic
+ # Reference {'x': x, 'y': y, 'z': z, 'time': self.startTime, 'cmd_id': self.msgID}
+ self.topicFormats = {'swing': {},'food': {},}
+
+ executeAction = lambda mem, midcaAction, status: self.send_point()
+ completionCheck = lambda mem, midcaAction, status: self.check_confirmation()
+ AsynchAction.__init__(self, mem, midcaAction, executeAction,
+ completionCheck, True)
+
+
+
+ def send_topic(self):
+
+ for topic in self.topics:
+ # Handle
+ self.msgDict = topicFormats[topic]
+
+ print self.msgDict
+
+ print "trying to send"
+ print topic
+
+ sent = rosrun.send_msg(topic, rosrun.dict_as_msg(self.msgDict))
+ if not sent:
+ if verbose >= 1:
+ print "Fail"
+ self.status = FAILED
+
+ def check_confirmation(self):
+ checkTime = self.lastCheck
+ self.lastCheck = midcatime.now()
+ feedback = self.mem.get(self.mem.FEEDBACK)
+ if not feedback:
+ return False
+ for item in reversed(feedback):
+ #if all items have been checked, either in this check or previous, return
+ if item['received_at'] - checkTime < 0:
+ return False
+ #else see if item is a completion or failure message with id == self.msgID
+ if item[CMD_ID_KEY] == self.msgID:
+ if item[FEEDBACK_KEY] == COMPLETE:
+ return True
+ elif item[FEEDBACK_KEY] == FAILED:
+ self.status = FAILED
+ if verbose >= 1:
+ print "MIDCA received feedback that action", self, "has failed"
+ return False
+ return False
+
+class placeBlock(AsynchAction):
+
+ def __init__(self, mem, midcaAction, objectOrID, maxAllowedLag, maxDuration, topics,
+ msgID):
+ self.objectOrID = objectOrID
+ self.maxAllowedLag = maxAllowedLag
+ self.maxDuration = maxDuration
+ self.lastCheck = 0.0
+ self.topics = topics
+ self.complete = False
+ self.msgID = msgID
+ # TODO: fill in formats for each topic
+ # Reference {'x': x, 'y': y, 'z': z, 'time': self.startTime, 'cmd_id': self.msgID}
+ self.topicFormats = {'aim': {},'swing': {},}
+
+ executeAction = lambda mem, midcaAction, status: self.send_point()
+ completionCheck = lambda mem, midcaAction, status: self.check_confirmation()
+ AsynchAction.__init__(self, mem, midcaAction, executeAction,
+ completionCheck, True)
+
+
+
+ def send_topic(self):
+
+ for topic in self.topics:
+ # Handle
+ self.msgDict = topicFormats[topic]
+
+ print self.msgDict
+
+ print "trying to send"
+ print topic
+
+ sent = rosrun.send_msg(topic, rosrun.dict_as_msg(self.msgDict))
+ if not sent:
+ if verbose >= 1:
+ print "Fail"
+ self.status = FAILED
+
+ def check_confirmation(self):
+ checkTime = self.lastCheck
+ self.lastCheck = midcatime.now()
+ feedback = self.mem.get(self.mem.FEEDBACK)
+ if not feedback:
+ return False
+ for item in reversed(feedback):
+ #if all items have been checked, either in this check or previous, return
+ if item['received_at'] - checkTime < 0:
+ return False
+ #else see if item is a completion or failure message with id == self.msgID
+ if item[CMD_ID_KEY] == self.msgID:
+ if item[FEEDBACK_KEY] == COMPLETE:
+ return True
+ elif item[FEEDBACK_KEY] == FAILED:
+ self.status = FAILED
+ if verbose >= 1:
+ print "MIDCA received feedback that action", self, "has failed"
+ return False
+ return False
+
+
diff --git a/midca/domains/nbeacons/domains/nbeacons.sim b/midca/domains/nbeacons/nbeacons.sim
similarity index 100%
rename from midca/domains/nbeacons/domains/nbeacons.sim
rename to midca/domains/nbeacons/nbeacons.sim
diff --git a/midca/domains/restaurant_domain/domains/restaurant.sim b/midca/domains/restaurant_domain/restaurant.sim
similarity index 100%
rename from midca/domains/restaurant_domain/domains/restaurant.sim
rename to midca/domains/restaurant_domain/restaurant.sim
diff --git a/midca/examples/Logistics_jshop.py b/midca/examples/Logistics_jshop.py
index 4b3effc0..726a8310 100644
--- a/midca/examples/Logistics_jshop.py
+++ b/midca/examples/Logistics_jshop.py
@@ -24,7 +24,7 @@
### Domain Specific Variables
DOMAIN_ROOT = MIDCA_ROOT + "domains/logistics/"
-DOMAIN_FILE = DOMAIN_ROOT + "domains/domain2.sim"
+DOMAIN_FILE = DOMAIN_ROOT + "domain2.sim"
STATE_FILE = DOMAIN_ROOT + "states/defstate2.sim"
### Domain Specific Variables for JSHOP planner
diff --git a/midca/examples/chicken_run.py b/midca/examples/chicken_run.py
index 765f02d8..5e2170e4 100644
--- a/midca/examples/chicken_run.py
+++ b/midca/examples/chicken_run.py
@@ -19,7 +19,7 @@
### Domain Specific Variables
DOMAIN_ROOT = MIDCA_ROOT + "domains/blocksworld/"
-DOMAIN_FILE = DOMAIN_ROOT + "domains/sample_domain.sim"
+DOMAIN_FILE = DOMAIN_ROOT + "sample_domain.sim"
STATE_FILE = DOMAIN_ROOT + "states/sample_state.sim"
DISPLAY_FUNC = print
DECLARE_METHODS_FUNC = sample_methods.declare_methods
diff --git a/midca/examples/cogsci_demo.py b/midca/examples/cogsci_demo.py
index 85a482d5..d03170a5 100644
--- a/midca/examples/cogsci_demo.py
+++ b/midca/examples/cogsci_demo.py
@@ -21,7 +21,7 @@
### Domain Specific Variables
DOMAIN_ROOT = MIDCA_ROOT + "domains/blocksworld/"
-DOMAIN_FILE = DOMAIN_ROOT + "domains/arsonist.sim"
+DOMAIN_FILE = DOMAIN_ROOT + "arsonist.sim"
STATE_FILE = DOMAIN_ROOT + "states/defstate.sim"
DISPLAY_FUNC = util.asqiiDisplay
DECLARE_METHODS_FUNC = methods.declare_methods
diff --git a/midca/examples/cogsci_demo_ma.py b/midca/examples/cogsci_demo_ma.py
index cc5bb896..ba75d588 100644
--- a/midca/examples/cogsci_demo_ma.py
+++ b/midca/examples/cogsci_demo_ma.py
@@ -29,7 +29,7 @@
util.pyhop_tasks_from_goals,
DECLARE_METHODS_FUNC,
DECLARE_OPERATORS_FUNC]
-myMidca = predicateworld.UserGoalsMidca(domainFile = MIDCA_ROOT + "domains/blocksworld/domains/arsonist.sim", stateFile = MIDCA_ROOT + "domains/blocksworld/states/defstate.sim", display = DISPLAY_FUNC, argsPyHopPlanner=argsPyHopPlanner)
+myMidca = predicateworld.UserGoalsMidca(domainFile = MIDCA_ROOT + "domains/blocksworld/arsonist.sim", stateFile = MIDCA_ROOT + "domains/blocksworld/states/defstate.sim", display = DISPLAY_FUNC, argsPyHopPlanner=argsPyHopPlanner)
myMidca.append_module('Perceive', perceive.MAReporter(writePort))
myMidca.insert_module('Simulate', simulator.ArsonSimulator(arsonChance = 0.9, arsonStart = 2), 1)
diff --git a/midca/examples/cogsci_demo_mortar.py b/midca/examples/cogsci_demo_mortar.py
index 93bcbe6f..0591c049 100644
--- a/midca/examples/cogsci_demo_mortar.py
+++ b/midca/examples/cogsci_demo_mortar.py
@@ -22,7 +22,7 @@
### Domain Specific Variables
DOMAIN_ROOT = MIDCA_ROOT + "domains/blocksworld/"
-DOMAIN_FILE = DOMAIN_ROOT + "domains/arsonist_mortar.sim"
+DOMAIN_FILE = DOMAIN_ROOT + "arsonist_mortar.sim"
STATE_FILE = DOMAIN_ROOT + "states/defstate_mortar.sim"
DISPLAY_FUNC = util.asqiiDisplay
DECLARE_METHODS_FUNC = methods_mortar.declare_methods
diff --git a/midca/examples/cogsci_demo_mortar_construction.py b/midca/examples/cogsci_demo_mortar_construction.py
index 118e9679..ebc9751e 100644
--- a/midca/examples/cogsci_demo_mortar_construction.py
+++ b/midca/examples/cogsci_demo_mortar_construction.py
@@ -25,7 +25,7 @@
MIDCA_ROOT = thisDir + "/../"
DOMAIN_ROOT = MIDCA_ROOT + "domains/construction_domain/"
-DOMAIN_FILE = DOMAIN_ROOT + "domains/arsonist_mortar_construction.sim"
+DOMAIN_FILE = DOMAIN_ROOT + "arsonist_mortar_construction.sim"
STATE_FILE = DOMAIN_ROOT + "states/defstate_construction.sim"
DISPLAY_FUNC = util.asqiiDisplay
diff --git a/midca/examples/cogsci_demo_mortar_goal_transforms.py b/midca/examples/cogsci_demo_mortar_goal_transforms.py
index 4f223748..13cf41a0 100644
--- a/midca/examples/cogsci_demo_mortar_goal_transforms.py
+++ b/midca/examples/cogsci_demo_mortar_goal_transforms.py
@@ -27,7 +27,7 @@
MIDCA_ROOT = thisDir + "/../"
### Domain Specific Variables
DOMAIN_ROOT = MIDCA_ROOT + "domains/blocksworld/"
-DOMAIN_FILE = DOMAIN_ROOT + "domains/arsonist_mortar.sim"
+DOMAIN_FILE = DOMAIN_ROOT + "arsonist_mortar.sim"
STATE_FILE = DOMAIN_ROOT + "states/defstate_mortar.sim"
DISPLAY_FUNC = util.asqiiDisplay
DECLARE_METHODS_FUNC = methods_mortar.declare_methods
diff --git a/midca/examples/minecraft_run.py b/midca/examples/minecraft_run.py
new file mode 100644
index 00000000..db132b8b
--- /dev/null
+++ b/midca/examples/minecraft_run.py
@@ -0,0 +1,63 @@
+import midca
+from midca import base
+from midca.modules import simulator, guide, evaluate, perceive, intend, planning, act, note, assess
+from midca.worldsim import domainread, stateread
+import inspect, os
+
+# Domain Specific Imports
+from midca.domains.minecraft import minecraft_util
+# TODO: This will have to be reworked when the file system is updated. I do not have access to my office and whiteboard drawings
+from midca.domains.minecraft.plan import methods_minecraft, operators_minecraft
+
+'''
+This template has been automatically created for your new domain, minecraft.
+'''
+
+# Setup
+thisDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
+MIDCA_ROOT = thisDir + "/../"
+
+### Domain Specific Variables
+DOMAIN_ROOT = MIDCA_ROOT + "domains/minecraft/"
+# TODO: Next 2 lines will have to be reworked when the file system is updated. I do not have access to my office and whiteboard drawings
+DOMAIN_FILE = DOMAIN_ROOT + "domain.sim"
+STATE_FILE = DOMAIN_ROOT + "states/state.sim"
+DISPLAY_FUNC = print
+DECLARE_METHODS_FUNC = methods.declare_methods # TODO: add your domain methods to midca/domains/minecraft/plan/methods.py
+DECLARE_OPERATORS_FUNC = operators.declare_ops # TODO: add your domain operators to midca/domains/minecraft/plan/operators.py
+
+
+# Load Domain Files
+world = domainread.load_domain(DOMAIN_FILE)
+stateread.apply_state_file(world, STATE_FILE)
+
+# Creates a PhaseManager object, which wraps a MIDCA object
+myMidca = base.PhaseManager(world, display = DISPLAY_FUNC, verbose=4)
+
+# Add phases by name
+for phase in ["Simulate", "Perceive", "Interpret", "Eval", "Intend", "Plan", "Act"]:
+ myMidca.append_phase(phase)
+
+
+# TODO: Update the module references to be domain specific functions
+# Add the modules which instantiate basic operation
+myMidca.append_module("Simulate", simulator.MidcaActionSimulator())
+myMidca.append_module("Perceive", perceive.PerfectObserver())
+myMidca.append_module("Interpret", guide.UserGoalInput())
+myMidca.append_module("Eval", evaluate.SimpleEval())
+myMidca.append_module("Intend", intend.SimpleIntend())
+myMidca.append_module("Plan", planning.GenericPyhopPlanner(
+ DECLARE_METHODS_FUNC, DECLARE_OPERATORS_FUNC)) # set up planner for sample domain
+myMidca.append_module("Act", act.SimpleAct())
+
+# Set world viewer with your specified DISPLAY_FUNC
+myMidca.set_display_function(DISPLAY_FUNC)
+
+# Tells the PhaseManager to copy and store MIDCA states so they can be accessed later.
+# Note: Turning this on drastically increases MIDCA's running time.
+myMidca.storeHistory = False
+myMidca.mem.logEachAccess = False
+
+# Initialize and start running!
+myMidca.init()
+myMidca.run()
\ No newline at end of file
diff --git a/midca/examples/nbeacons_aaai17_agent1.py b/midca/examples/nbeacons_aaai17_agent1.py
index 5e4167c4..ffdca178 100644
--- a/midca/examples/nbeacons_aaai17_agent1.py
+++ b/midca/examples/nbeacons_aaai17_agent1.py
@@ -28,7 +28,7 @@
### Domain Specific Variables
DOMAIN_ROOT = MIDCA_ROOT + "domains/nbeacons/"
-DOMAIN_FILE = DOMAIN_ROOT + "domains/nbeacons.sim"
+DOMAIN_FILE = DOMAIN_ROOT + "nbeacons.sim"
#STATE_FILE = DOMAIN_ROOT + "states/.sim" # state file is generated dynamically
DISPLAY_FUNC = nbeacons_util.drawNBeaconsScene
DECLARE_METHODS_FUNC = methods_nbeacons.declare_methods
diff --git a/midca/examples/nbeacons_aaai17_agent2.py b/midca/examples/nbeacons_aaai17_agent2.py
index c28d5a51..0e7aea5c 100644
--- a/midca/examples/nbeacons_aaai17_agent2.py
+++ b/midca/examples/nbeacons_aaai17_agent2.py
@@ -30,7 +30,7 @@
### Domain Specific Variables
DOMAIN_ROOT = MIDCA_ROOT + "domains/nbeacons/"
-DOMAIN_FILE = DOMAIN_ROOT + "domains/nbeacons.sim"
+DOMAIN_FILE = DOMAIN_ROOT + "nbeacons.sim"
#STATE_FILE = DOMAIN_ROOT + "states/.sim" # state file is generated dynamically
DISPLAY_FUNC = nbeacons_util.drawNBeaconsScene
DECLARE_METHODS_FUNC = methods_nbeacons.declare_methods
diff --git a/midca/examples/nbeacons_aaai17_agent3.py b/midca/examples/nbeacons_aaai17_agent3.py
index fca24e52..6accf628 100644
--- a/midca/examples/nbeacons_aaai17_agent3.py
+++ b/midca/examples/nbeacons_aaai17_agent3.py
@@ -45,7 +45,7 @@
### Domain Specific Variables
DOMAIN_ROOT = MIDCA_ROOT + "domains/nbeacons/"
-DOMAIN_FILE = DOMAIN_ROOT + "domains/nbeacons_avoid_mud.sim"
+DOMAIN_FILE = DOMAIN_ROOT + "nbeacons_avoid_mud.sim"
#STATE_FILE = DOMAIN_ROOT + "states/.sim" # state file is generated dynamically
DISPLAY_FUNC = nbeacons_util.drawNBeaconsScene
DECLARE_METHODS_FUNC = methods_nbeacons.declare_methods
diff --git a/midca/examples/nbeacons_demo.py b/midca/examples/nbeacons_demo.py
index 4ef4b806..403ec3b4 100644
--- a/midca/examples/nbeacons_demo.py
+++ b/midca/examples/nbeacons_demo.py
@@ -21,7 +21,7 @@
### Domain Specific Variables
DOMAIN_ROOT = MIDCA_ROOT + "domains/nbeacons/"
-DOMAIN_FILE = DOMAIN_ROOT + "domains/nbeacons.sim"
+DOMAIN_FILE = DOMAIN_ROOT + "nbeacons.sim"
#STATE_FILE = DOMAIN_ROOT + "states/.sim" # state file is generated dynamically
DISPLAY_FUNC = nbeacons_util.drawNBeaconsScene
DECLARE_METHODS_FUNC = methods_nbeacons.declare_methods
diff --git a/midca/examples/restaurant_demo.py b/midca/examples/restaurant_demo.py
index eccd1dda..b2f26cf1 100644
--- a/midca/examples/restaurant_demo.py
+++ b/midca/examples/restaurant_demo.py
@@ -25,7 +25,7 @@
MIDCA_ROOT = thisDir + "/../"
DOMAIN_ROOT = MIDCA_ROOT + "domains/restaurant_domain/"
-DOMAIN_FILE = DOMAIN_ROOT + "domains/restaurant.sim"
+DOMAIN_FILE = DOMAIN_ROOT + "restaurant.sim"
STATE_FILE = DOMAIN_ROOT + "states/restaurant_state.sim"
DISPLAY_FUNC = util.shopping_display
diff --git a/midca/examples/run_extinguish.py b/midca/examples/run_extinguish.py
index 2116a9fe..0a756326 100644
--- a/midca/examples/run_extinguish.py
+++ b/midca/examples/run_extinguish.py
@@ -16,7 +16,7 @@
MIDCA_ROOT = thisDir + "/../"
-domainFile = MIDCA_ROOT + "domains/blocksworld/domains/arsonist_extinguish.sim"
+domainFile = MIDCA_ROOT + "domains/blocksworld/arsonist_extinguish.sim"
stateFile = MIDCA_ROOT + "domains/blocksworld/states/extinguisher_state.sim"
extinguish = True
diff --git a/midca/examples/simple_run.py b/midca/examples/simple_run.py
index 6ce5f2e7..7db2e89f 100644
--- a/midca/examples/simple_run.py
+++ b/midca/examples/simple_run.py
@@ -25,7 +25,7 @@
myMidca = predicateworld.UserGoalsMidca(domainFile = MIDCA_ROOT +
- "domains/blocksworld/domains/arsonist.sim",
+ "domains/blocksworld/arsonist.sim",
stateFile = MIDCA_ROOT + "domains/blocksworld/states/defstate_fire.sim",
argsPyHopPlanner=argsPyHopPlanner)
#tells the PhaseManager to copy and store MIDCA states so they can be accessed later. Note: this drastically increases MIDCA's running time.
diff --git a/midca/examples/simple_run_arson.py b/midca/examples/simple_run_arson.py
index 850490f4..f18b5ff1 100644
--- a/midca/examples/simple_run_arson.py
+++ b/midca/examples/simple_run_arson.py
@@ -14,7 +14,7 @@
### Domain Specific Variables
DOMAIN_ROOT = MIDCA_ROOT + "domains/blocksworld/"
-DOMAIN_FILE = DOMAIN_ROOT + "domains/arsonist_extinguish.sim"
+DOMAIN_FILE = DOMAIN_ROOT + "arsonist_extinguish.sim"
STATE_FILE = DOMAIN_ROOT + "states/extinguisher_state.sim"
DISPLAY_FUNC = util.asqiiDisplay
DECLARE_METHODS_FUNC = methods_extinguish.declare_methods
diff --git a/midca/examples/simple_run_arson_broken_shop_methods.py b/midca/examples/simple_run_arson_broken_shop_methods.py
index 4e697ed9..6e95ffe0 100644
--- a/midca/examples/simple_run_arson_broken_shop_methods.py
+++ b/midca/examples/simple_run_arson_broken_shop_methods.py
@@ -19,7 +19,7 @@ def asqiiDisplay(world):
### Domain Specific Variables
DOMAIN_ROOT = MIDCA_ROOT + "domains/blocksworld/"
-DOMAIN_FILE = DOMAIN_ROOT + "domains/arsonist.sim"
+DOMAIN_FILE = DOMAIN_ROOT + "arsonist.sim"
STATE_FILE = DOMAIN_ROOT + "states/defstate_fire_pyhop_inducing_bug.sim"
DISPLAY_FUNC = util.asqiiDisplay
DECLARE_METHODS_FUNC = methods_broken.declare_methods
diff --git a/midca/examples/simple_run_arson_not_prefer_fire.py b/midca/examples/simple_run_arson_not_prefer_fire.py
index 4828adcc..d5a96634 100644
--- a/midca/examples/simple_run_arson_not_prefer_fire.py
+++ b/midca/examples/simple_run_arson_not_prefer_fire.py
@@ -19,7 +19,7 @@
DECLARE_METHODS_FUNC,
DECLARE_OPERATORS_FUNC]
-myMidca = predicateworld.UserGoalsMidca(domainFile = MIDCA_ROOT + "domains/blocksworld/domains/arsonist.sim", stateFile = MIDCA_ROOT + "domains/blocksworld/states/defstate_fire.sim", argsPyHopPlanner=argsPyHopPlanner)
+myMidca = predicateworld.UserGoalsMidca(domainFile = MIDCA_ROOT + "domains/blocksworld/arsonist.sim", stateFile = MIDCA_ROOT + "domains/blocksworld/states/defstate_fire.sim", argsPyHopPlanner=argsPyHopPlanner)
myMidca.insert_module('Simulate', simulator.ArsonSimulator(arsonChance = 0.3, arsonStart = 2), 1)
myMidca.insert_module('Interpret', guide.TFStack(), 1)
diff --git a/midca/examples/simple_run_arson_trace.py b/midca/examples/simple_run_arson_trace.py
index 4828adcc..d5a96634 100644
--- a/midca/examples/simple_run_arson_trace.py
+++ b/midca/examples/simple_run_arson_trace.py
@@ -19,7 +19,7 @@
DECLARE_METHODS_FUNC,
DECLARE_OPERATORS_FUNC]
-myMidca = predicateworld.UserGoalsMidca(domainFile = MIDCA_ROOT + "domains/blocksworld/domains/arsonist.sim", stateFile = MIDCA_ROOT + "domains/blocksworld/states/defstate_fire.sim", argsPyHopPlanner=argsPyHopPlanner)
+myMidca = predicateworld.UserGoalsMidca(domainFile = MIDCA_ROOT + "domains/blocksworld/arsonist.sim", stateFile = MIDCA_ROOT + "domains/blocksworld/states/defstate_fire.sim", argsPyHopPlanner=argsPyHopPlanner)
myMidca.insert_module('Simulate', simulator.ArsonSimulator(arsonChance = 0.3, arsonStart = 2), 1)
myMidca.insert_module('Interpret', guide.TFStack(), 1)
diff --git a/midca/examples/simple_run_jshop.py b/midca/examples/simple_run_jshop.py
index 32ac44e9..8020a88a 100644
--- a/midca/examples/simple_run_jshop.py
+++ b/midca/examples/simple_run_jshop.py
@@ -33,7 +33,7 @@
print MIDCA_ROOT
### Domain Specific Variables
DOMAIN_ROOT = MIDCA_ROOT + "domains/blocksworld/"
-DOMAIN_FILE = DOMAIN_ROOT + "domains/arsonist.sim"
+DOMAIN_FILE = DOMAIN_ROOT + "arsonist.sim"
STATE_FILE = DOMAIN_ROOT + "states/defstate_jshop.sim"
### Domain Specific Variables for JSHOP planner
diff --git a/midca/examples/simple_run_log.py b/midca/examples/simple_run_log.py
index 69ed8253..70cc1104 100644
--- a/midca/examples/simple_run_log.py
+++ b/midca/examples/simple_run_log.py
@@ -24,7 +24,7 @@
DECLARE_OPERATORS_FUNC]
-myMidca = predicateworld.UserGoalsMidca(domainFile = MIDCA_ROOT + "domains/blocksworld/domains/arsonist.sim", stateFile = MIDCA_ROOT + "domains/blocksworld/states/defstate_fire.sim", argsPyHopPlanner=argsPyHopPlanner)
+myMidca = predicateworld.UserGoalsMidca(domainFile = MIDCA_ROOT + "domains/blocksworld/arsonist.sim", stateFile = MIDCA_ROOT + "domains/blocksworld/states/defstate_fire.sim", argsPyHopPlanner=argsPyHopPlanner)
#tells the PhaseManager to copy and store MIDCA states so they can be accessed later. Note: this drastically increases MIDCA's running time.
myMidca.storeHistory = True
diff --git a/midca/examples/simple_run_trace.py b/midca/examples/simple_run_trace.py
index e255721f..bb442c2f 100644
--- a/midca/examples/simple_run_trace.py
+++ b/midca/examples/simple_run_trace.py
@@ -20,7 +20,7 @@
DECLARE_OPERATORS_FUNC]
-myMidca = predicateworld.UserGoalsMidca(domainFile = MIDCA_ROOT + "domains/blocksworld/domains/arsonist.sim", stateFile = MIDCA_ROOT + "domains/blocksworld/states/defstate_fire.sim", argsPyHopPlanner=argsPyHopPlanner)
+myMidca = predicateworld.UserGoalsMidca(domainFile = MIDCA_ROOT + "domains/blocksworld/arsonist.sim", stateFile = MIDCA_ROOT + "domains/blocksworld/states/defstate_fire.sim", argsPyHopPlanner=argsPyHopPlanner)
#tells the PhaseManager to copy and store MIDCA states so they can be accessed later.
myMidca.storeHistory = True
diff --git a/setup.py b/setup.py
index f3e25670..92926309 100755
--- a/setup.py
+++ b/setup.py
@@ -44,4 +44,4 @@
'': ['*.txt', 'midca.domains.logistics'],
'': ['*.*', 'midca.modules._plan.jShop'],
'': ['*.shp', 'midca.domains.jshop_domains.blocks_world']},
- )
+ )
\ No newline at end of file