Skip to content

Commit 9ab0663

Browse files
committed
Added evaluation script
1 parent 4e70107 commit 9ab0663

File tree

4 files changed

+127
-17
lines changed

4 files changed

+127
-17
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
evaluation.yaml
2+
envtest/ros/summary.yaml
13

24
# Python stuff
35
*.pyc

envtest/ros/evaluation_config.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ topics:
66
finish: "finish_navigation"
77

88
target: 60 # must be INTEGER
9+
timeout: 30
10+
bounding_box: [-5, 65, -10, 10, 0, 10]
911

1012
# if you really don't want the cool plots, put this to False
1113
plots: True

envtest/ros/evaluation_node.py

+59-17
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,32 @@ def __init__(self, config):
2525

2626
self.hit_obstacle = False
2727
self.crash = 0
28-
28+
self.timeout = self.config['timeout']
29+
self.bounding_box = np.reshape(np.array(
30+
self.config['bounding_box'], dtype=float), (3,2)).T
31+
2932
self._initSubscribers(config['topics'])
3033
self._initPublishers(config['topics'])
3134

3235

3336
def _initSubscribers(self, config):
3437
self.state_sub = rospy.Subscriber(
3538
"/%s/%s" % (config['quad_name'], config['state']),
36-
QuadState,
39+
QuadState,
3740
self.callbackState,
3841
queue_size=1,
3942
tcp_nodelay=True)
40-
43+
4144
self.obstacle_sub = rospy.Subscriber(
4245
"/%s/%s" % (config['quad_name'], config['obstacles']),
43-
ObstacleArray,
46+
ObstacleArray,
4447
self.callbackObstacles,
4548
queue_size=1,
4649
tcp_nodelay=True)
4750

4851
self.start_sub = rospy.Subscriber(
4952
"/%s/%s" % (config['quad_name'], config['start']),
50-
Empty,
53+
Empty,
5154
self.callbackStart,
5255
queue_size=1,
5356
tcp_nodelay=True)
@@ -70,12 +73,11 @@ def callbackState(self, msg):
7073
if not self.is_active:
7174
return
7275

73-
self.pos.append(np.array(
74-
[msg.header.stamp.to_sec(),
75-
msg.pose.position.x,
76-
msg.pose.position.y,
77-
msg.pose.position.z]
78-
))
76+
pos = np.array([msg.header.stamp.to_sec(),
77+
msg.pose.position.x,
78+
msg.pose.position.y,
79+
msg.pose.position.z])
80+
self.pos.append(pos)
7981

8082
pos_x = msg.pose.position.x
8183
bin_x = int(max(min(np.floor(pos_x),self.xmax),0))
@@ -86,38 +88,76 @@ def callbackState(self, msg):
8688
self.is_active = False
8789
self.publishFinish()
8890

91+
if rospy.get_time() - self.time_array[0] > self.timeout:
92+
self.abortRun()
93+
94+
outside = ((pos[1:] > self.bounding_box[1,:])
95+
| (pos[1:] < self.bounding_box[0,:])).any(axis=-1)
96+
if (outside == True).any():
97+
self.abortRun()
98+
99+
89100

90101
def callbackStart(self, msg):
91-
self.is_active = True
102+
if not self.is_active:
103+
self.is_active = True
92104
self.time_array[0] = rospy.get_rostime().to_sec()
93105

94106

95107
def callbackObstacles(self, msg):
96108
if not self.is_active:
97109
return
98-
110+
99111
obs = msg.obstacles[0]
100-
dist = np.linalg.norm(np.array([obs.position.x,
101-
obs.position.y,
112+
dist = np.linalg.norm(np.array([obs.position.x,
113+
obs.position.y,
102114
obs.position.z]))
103115
margin = dist - obs.scale/2
104116
self.dist.append([msg.header.stamp.to_sec(), margin])
105117
if margin < 0:
106118
if not self.hit_obstacle:
107119
self.crash += 1
120+
print("Crashed")
108121
self.hit_obstacle = True
109122
else:
110123
self.hit_obstacle = False
111124

112125

126+
def abortRun(self):
127+
print("You did not reach the goal!")
128+
summary = {}
129+
summary['Success'] = False
130+
with open("summary.yaml", "w") as f:
131+
if os.getenv('ROLLOUT_NAME') is not None:
132+
tmp = {}
133+
tmp[os.getenv('ROLLOUT_NAME')] = summary
134+
yaml.safe_dump(tmp, f)
135+
else:
136+
yaml.safe_dump(summary, f)
137+
rospy.signal_shutdown("Completed Evaluation")
138+
139+
113140
def printSummary(self):
114141
ttf = self.time_array[-1] - self.time_array[0]
142+
summary = {}
143+
summary['Success'] = True if self.crash == 0 else False
115144
print("You reached the goal in %5.3f seconds" % ttf)
145+
summary['time_to_finish'] = ttf
116146
print("Your intermediate times are:")
117147
print_distance = 10
118-
for i in range(print_distance, self.xmax-print_distance+1, print_distance):
148+
summary['segment_times'] = {}
149+
for i in range(print_distance, self.xmax+1, print_distance):
119150
print(" %2i: %5.3fs " % (i,self.time_array[i] - self.time_array[0]))
151+
summary['segment_times']["%i" % i] = self.time_array[i] - self.time_array[0]
120152
print("You hit %i obstacles" % self.crash)
153+
summary['number_crashes'] = self.crash
154+
with open("summary.yaml", "w") as f:
155+
if os.getenv('ROLLOUT_NAME') is not None:
156+
tmp = {}
157+
tmp[os.getenv('ROLLOUT_NAME')] = summary
158+
yaml.safe_dump(tmp, f)
159+
else:
160+
yaml.safe_dump(summary, f)
121161

122162
if not self.config['plots']:
123163
return
@@ -131,11 +171,13 @@ def printSummary(self):
131171
dt = np.array(self.time_array)
132172
y = 1/(dt[1:]-dt[0:-1])
133173
plot(xs=x, ys=y, color=True)
134-
174+
135175
print("Here is a plot of the distance to the closest obstacles")
136176
dist = np.array(self.dist)
137177
plot(xs=dist[:,0]-self.time_array[0], ys=dist[:,1], color=True)
138178

179+
rospy.signal_shutdown("Completed Evaluation")
180+
139181

140182

141183
if __name__=="__main__":

launch_evaluation.bash

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#!/bin/bash
2+
3+
# Pass number of rollouts as argument
4+
if [ $1 ]
5+
then
6+
N="$1"
7+
else
8+
N=10
9+
fi
10+
11+
# Set Flightmare Path if it is not set
12+
if [ -z $FLIGHTMARE_PATH ]
13+
then
14+
export FLIGHTMARE_PATH=$PWD/flightmare
15+
fi
16+
17+
# Launch the simulator, unless it is already running
18+
if [ -z $(pgrep visionsim_node) ]
19+
then
20+
roslaunch envsim visionenv_sim.launch render:=True &
21+
ROS_PID="$!"
22+
echo $ROS_PID
23+
sleep 10
24+
else
25+
ROS_PID=""
26+
fi
27+
28+
SUMMARY_FILE="evaluation.yaml"
29+
"" > $SUMMARY_FILE
30+
31+
# Perform N evaluation runs
32+
for i in $(eval echo {1..$N})
33+
do
34+
# Publish simulator reset
35+
rostopic pub /kingfisher/agiros_pilot/off std_msgs/Empty "{}" --once
36+
rostopic pub /kingfisher/agiros_pilot/reset_sim std_msgs/Empty "{}" --once
37+
rostopic pub /kingfisher/agiros_pilot/enable std_msgs/Bool "data: true" --once
38+
39+
export ROLLOUT_NAME="rollout_""$i"
40+
echo "$ROLLOUT_NAME"
41+
42+
cd ./envtest/ros/
43+
python evaluation_node.py &
44+
PY_PID="$!"
45+
cd -
46+
47+
sleep 0.5
48+
rostopic pub /kingfisher/start_navigation std_msgs/Empty "{}" --once
49+
50+
# Wait until the evaluation script has finished
51+
while ps -p $PY_PID > /dev/null
52+
do
53+
sleep 1
54+
done
55+
56+
cat "$SUMMARY_FILE" "./envtest/ros/summary.yaml" > "tmp.yaml"
57+
mv "tmp.yaml" "$SUMMARY_FILE"
58+
done
59+
60+
61+
if [ $ROS_PID ]
62+
then
63+
kill -SIGINT "$ROS_PID"
64+
fi

0 commit comments

Comments
 (0)