-
Notifications
You must be signed in to change notification settings - Fork 1
/
grader.py
87 lines (75 loc) · 3.89 KB
/
grader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import numpy as np
import pdb
import argparse
import subprocess # For executing c++ executable
import pandas as pd
from timeit import default_timer as timer
###############################################################
################### Util Functions Below ######################
def convertPIs(aString):
""" Input: A comma seperated string like "pi/2,pi/4,pi/2,pi/4,pi/2,"
or 1.2,4,5.3 etc
Output: string replacing the pis 1.57079,...,...
"""
if aString[-1] == ",": # Remove training comma if there is one
aString = aString[:-1]
aString = aString.replace("pi", "3.141592") # Replace pi with 3.14... if needed
vecOfStrings = aString.split(",")
ans = []
for anExpression in vecOfStrings:
ans.append(str(eval(anExpression))) # Evaluate expressions if needed
return ans
###############################################################
################### Main Functions Below ######################
def graderMain(executablePath, gradingCSV):
problems = [["./map1.txt", "pi/2,pi/4,pi/2,0.785398,1.570796",
"0.392699,2.356194,pi,2.8274328,pi*3/2"],
["./map2.txt", "0.392699,2.356194,3.141592",
"1.570796,0.785398,1.570796"]]
scores = []
for aPlanner in [0, 1, 2, 3]:
for i, data in enumerate(problems):
inputMap, startPos, goalPos = [*data]
numDOFs = len(startPos.split(","))
outputSolutionFile = "tmp.txt"
startPosString = ",".join(convertPIs(startPos))
goalPosString = ",".join(convertPIs(goalPos))
commandPlan = "{} {} {} {} {} {} {}".format(
executablePath,
inputMap, numDOFs, startPosString, goalPosString,
aPlanner, outputSolutionFile)
commandVerify = "./a.exe {} {} {} {} {}".format(
inputMap, numDOFs, startPosString, goalPosString,
outputSolutionFile)
try:
start = timer()
subprocess.run(commandPlan.split(" "), check=True) # True if want to see failure errors
timespent = timer() - start
returncode = subprocess.run(commandVerify.split(" "), check=False).returncode
if returncode != 0:
print("Returned an invalid solution")
### Calculate the cost from their solution
with open(outputSolutionFile) as f:
line = f.readline().rstrip() # filepath of the map
solution = []
for line in f:
solution.append(line.split(",")[:-1]) # :-1 to drop trailing comma
solution = np.asarray(solution).astype(float)
numSteps = solution.shape[0]
## Cost is sum of all joint angle movements
difsPos = np.abs(solution[1:,]-solution[:-1,])
cost = np.minimum(difsPos, np.abs(2*np.pi - difsPos)).sum()
success = returncode == 0
scores.append([aPlanner, inputMap, i, numSteps, cost, timespent, success])
### Visualize their results
commandViz = "python visualizer.py tmp.txt --gifFilepath=grades_{}.gif".format(i)
commandViz += " --incPrev=1"
subprocess.run(commandViz.split(" "), check=True) # True if want to see failure errors
except Exception as exc:
print("Failed: {} !!".format(exc))
scores.append([aPlanner, inputMap, i, -1, -1, timespent, False])
### Save all the scores into a csv to compute overall grades
df = pd.DataFrame(scores, columns=["planner", "mapName", "problemIndex", "numSteps", "cost", "timespent", "success"])
df.to_csv(gradingCSV, index=False)
if __name__ == "__main__":
graderMain("./planner.out", "test.csv")