Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
emulab
emulab-devel
Commits
194773ba
Commit
194773ba
authored
Mar 04, 2005
by
Leigh B. Stoller
Browse files
Add exclusion and camera bound checking.
parent
274cc4bb
Changes
5
Hide whitespace changes
Inline
Side-by-side
robots/tracker/RoboTrack.java
View file @
194773ba
...
...
@@ -151,6 +151,12 @@ public class RoboTrack extends JApplet {
map
.
stop
();
}
// Simply for the benefit of running from the shell for testing.
public
void
init
(
boolean
fromshell
)
{
shelled
=
fromshell
;
init
();
}
/*
* A thing that waits for an image to be loaded.
*/
...
...
@@ -206,12 +212,33 @@ public class RoboTrack extends JApplet {
Vector
robotmap
=
new
Vector
(
10
,
10
);
int
robotcount
=
0
;
/*
* A container for obstacle information.
*/
private
class
Obstacle
{
int
id
;
// DB identifier; not actually used.
int
x1
,
y1
;
// Upper left x,y coords in pixels.
int
x2
,
y2
;
// Lower right x,y coords in pixels.
String
description
;
}
Vector
Obstacles
=
new
Vector
(
10
,
10
);
/*
* A container for camera information.
*/
private
class
Camera
{
String
name
;
// DB identifier; not actually used.
int
x1
,
y1
;
// Upper left x,y coords in pixels.
int
x2
,
y2
;
// Lower right x,y coords in pixels.
}
Vector
Cameras
=
new
Vector
(
10
,
10
);
private
class
Map
extends
JPanel
implements
Runnable
{
private
Thread
thread
;
private
BufferedImage
bimg
;
private
Graphics2D
G2
=
null
;
// The DOT radius.
// The DOT radius.
This is radius of the circle of the robot.
int
DOT_RAD
=
20
;
// The length of the orientation stick, from the center of the circle.
int
STICK_LEN
=
20
;
...
...
@@ -220,6 +247,13 @@ public class RoboTrack extends JApplet {
int
LABEL_Y
=
20
;
public
Map
()
{
/*
* Request obstacle list when a real applet.
*/
if
(!
shelled
)
{
GetObstacles
();
GetCameras
();
}
}
/*
...
...
@@ -362,11 +396,11 @@ public class RoboTrack extends JApplet {
while
(
e
.
hasMoreElements
())
{
Robot
robbie
=
(
Robot
)
e
.
nextElement
();
if
((
Math
.
abs
(
robbie
.
y
-
y
)
<
10
&&
Math
.
abs
(
robbie
.
x
-
x
)
<
10
)
||
if
((
Math
.
abs
(
robbie
.
y
-
y
)
<
DOT_RAD
/
2
&&
Math
.
abs
(
robbie
.
x
-
x
)
<
DOT_RAD
/
2
)
||
(
robbie
.
dragging
&&
Math
.
abs
(
robbie
.
drag_y
-
y
)
<
10
&&
Math
.
abs
(
robbie
.
drag_x
-
x
)
<
10
))
{
Math
.
abs
(
robbie
.
drag_y
-
y
)
<
DOT_RAD
/
2
&&
Math
.
abs
(
robbie
.
drag_x
-
x
)
<
DOT_RAD
/
2
))
{
return
robbie
.
pname
;
}
}
...
...
@@ -374,8 +408,114 @@ public class RoboTrack extends JApplet {
}
/*
* Draw some buttons.
* Check for overlap with exclusions zones (obstacles). We check
* all the robots that are dragging, and popup a dialog box if
* we find one. The user then has to fix it.
*
* XXX I am treating the robot as a square! Easier to calculate.
*
* XXX The value below (OBSTACLE_BUFFER) is hardwired in floormap
* code (where the base image is generated).
*/
int
OBSTACLE_BUFFER
=
23
;
public
boolean
CheckforCollisions
()
{
Enumeration
robot_enum
=
robots
.
elements
();
while
(
robot_enum
.
hasMoreElements
())
{
Robot
robbie
=
(
Robot
)
robot_enum
.
nextElement
();
if
(!
robbie
.
dragging
)
continue
;
int
rx1
=
robbie
.
drag_x
-
((
DOT_RAD
/
2
)
+
OBSTACLE_BUFFER
);
int
ry1
=
robbie
.
drag_y
-
((
DOT_RAD
/
2
)
+
OBSTACLE_BUFFER
);
int
rx2
=
robbie
.
drag_x
+
((
DOT_RAD
/
2
)
+
OBSTACLE_BUFFER
);
int
ry2
=
robbie
.
drag_y
+
((
DOT_RAD
/
2
)
+
OBSTACLE_BUFFER
);
//System.out.println("CheckCollision: " + rx1 + "," +
// ry1 + "," + rx2 + "," + ry2);
/*
* Check for overlap of this robot with each obstacle.
*/
for
(
int
index
=
0
;
index
<
Obstacles
.
size
();
index
++)
{
Obstacle
obstacle
=
(
Obstacle
)
Obstacles
.
elementAt
(
index
);
int
ox1
=
obstacle
.
x1
;
int
oy1
=
obstacle
.
y1
;
int
ox2
=
obstacle
.
x2
;
int
oy2
=
obstacle
.
y2
;
//System.out.println(" " + ox1 + "," +
// oy1 + "," + ox2 + "," + cy2);
if
(!
(
oy2
<
ry1
||
ry2
<
oy1
||
ox2
<
rx1
||
rx2
<
ox1
))
{
MyDialog
(
"Collision"
,
robbie
.
pname
+
" overlaps with an obstacle"
);
return
true
;
}
}
}
return
false
;
}
/*
* Check for robots wandering out of camera range. We check
* all the robots that are dragging, and popup a dialog box if
* we find one. The user then has to fix it.
*
* XXX I am treating the robot as a square! Easier to calculate.
*/
public
boolean
CheckOutOfBounds
()
{
Enumeration
robot_enum
=
robots
.
elements
();
while
(
robot_enum
.
hasMoreElements
())
{
Robot
robbie
=
(
Robot
)
robot_enum
.
nextElement
();
int
index
;
if
(!
robbie
.
dragging
)
continue
;
int
rx1
=
robbie
.
drag_x
-
((
DOT_RAD
/
2
));
int
ry1
=
robbie
.
drag_y
-
((
DOT_RAD
/
2
));
int
rx2
=
robbie
.
drag_x
+
((
DOT_RAD
/
2
));
int
ry2
=
robbie
.
drag_y
+
((
DOT_RAD
/
2
));
//System.out.println("CheckOutOfBounds: " + rx1 + "," +
// ry1 + "," + rx2 + "," + ry2);
/*
* Check for full overlap with at least one camera.
*/
for
(
index
=
0
;
index
<
Cameras
.
size
();
index
++)
{
Camera
camera
=
(
Camera
)
Cameras
.
elementAt
(
index
);
int
cx1
=
camera
.
x1
;
int
cy1
=
camera
.
y1
;
int
cx2
=
camera
.
x2
;
int
cy2
=
camera
.
y2
;
//System.out.println(" " + cx1 + "," +
// cy1 + "," + cx2 + "," + cy2);
if
((
rx1
>=
cx1
&&
ry1
>=
cy1
&&
rx2
<=
cx2
&&
ry2
<=
cy2
))
break
;
}
if
(
index
==
Cameras
.
size
())
{
MyDialog
(
"Out of Bounds"
,
robbie
.
pname
+
" is out of camera range"
);
return
true
;
}
}
return
false
;
}
/*
* Draw a robot, which is either the real one, a destination one,
...
...
@@ -1047,13 +1187,157 @@ public class RoboTrack extends JApplet {
maptable
.
clearSelection
();
}
else
if
(
source
==
SubmitMenuItem
)
{
SendInDestinations
();
/*
* Check for collisions before submitting.
*/
if
(!
map
.
CheckforCollisions
()
&&
!
map
.
CheckOutOfBounds
())
SendInDestinations
();
}
repaint
();
maptable
.
repaint
(
10
);
}
}
/*
* Get the Obstacle list from the server.
*/
public
boolean
GetObstacles
()
{
String
urlstring
=
"obstacles.php3?fromapplet=1"
+
"&nocookieuid="
+
URLEncoder
.
encode
(
uid
)
+
"&nocookieauth="
+
URLEncoder
.
encode
(
auth
);
try
{
URL
url
=
new
URL
(
getCodeBase
(),
urlstring
);
URLConnection
urlConn
;
InputStream
is
;
String
str
;
int
index
=
0
;
urlConn
=
url
.
openConnection
();
urlConn
.
setDoInput
(
true
);
urlConn
.
setUseCaches
(
false
);
is
=
urlConn
.
getInputStream
();
BufferedReader
input
=
new
BufferedReader
(
new
InputStreamReader
(
is
));
Obstacles
=
new
Vector
(
10
,
10
);
/*
* This should be in XML format.
*/
while
((
str
=
input
.
readLine
())
!=
null
)
{
System
.
out
.
println
(
str
);
StringTokenizer
tokens
=
new
StringTokenizer
(
str
,
","
);
String
tmp
;
Obstacle
obstacle
=
new
Obstacle
();
/*
* Convert from meters to pixels ...
*/
obstacle
.
id
=
Integer
.
parseInt
(
tokens
.
nextToken
().
trim
());
obstacle
.
x1
=
(
int
)
(
Double
.
parseDouble
(
tokens
.
nextToken
().
trim
())
*
pixels_per_meter
);
obstacle
.
y1
=
(
int
)
(
Double
.
parseDouble
(
tokens
.
nextToken
().
trim
())
*
pixels_per_meter
);
obstacle
.
x2
=
(
int
)
(
Double
.
parseDouble
(
tokens
.
nextToken
().
trim
())
*
pixels_per_meter
);
obstacle
.
y2
=
(
int
)
(
Double
.
parseDouble
(
tokens
.
nextToken
().
trim
())
*
pixels_per_meter
);
obstacle
.
description
=
tokens
.
nextToken
().
trim
();
Obstacles
.
insertElementAt
(
obstacle
,
index
++);
}
is
.
close
();
}
catch
(
Throwable
th
)
{
MyDialog
(
"GetObstacles"
,
"Failed to get obstacle list from server"
);
th
.
printStackTrace
();
return
false
;
}
return
true
;
}
/*
* Get the Camera list from the server.
*/
public
boolean
GetCameras
()
{
String
urlstring
=
"cameras.php3?fromapplet=1"
+
"&nocookieuid="
+
URLEncoder
.
encode
(
uid
)
+
"&nocookieauth="
+
URLEncoder
.
encode
(
auth
);
try
{
URL
url
=
new
URL
(
getCodeBase
(),
urlstring
);
URLConnection
urlConn
;
InputStream
is
;
String
str
;
int
index
=
0
;
urlConn
=
url
.
openConnection
();
urlConn
.
setDoInput
(
true
);
urlConn
.
setUseCaches
(
false
);
is
=
urlConn
.
getInputStream
();
BufferedReader
input
=
new
BufferedReader
(
new
InputStreamReader
(
is
));
Cameras
=
new
Vector
(
10
,
10
);
/*
* This should be in XML format.
*/
while
((
str
=
input
.
readLine
())
!=
null
)
{
System
.
out
.
println
(
str
);
StringTokenizer
tokens
=
new
StringTokenizer
(
str
,
","
);
String
tmp
;
Camera
camera
=
new
Camera
();
/*
* Convert from meters to pixels ...
*/
camera
.
name
=
tokens
.
nextToken
().
trim
();
camera
.
x1
=
(
int
)
(
Double
.
parseDouble
(
tokens
.
nextToken
().
trim
())
*
pixels_per_meter
);
camera
.
y1
=
(
int
)
(
Double
.
parseDouble
(
tokens
.
nextToken
().
trim
())
*
pixels_per_meter
);
camera
.
x2
=
(
int
)
(
Double
.
parseDouble
(
tokens
.
nextToken
().
trim
())
*
pixels_per_meter
);
camera
.
y2
=
(
int
)
(
Double
.
parseDouble
(
tokens
.
nextToken
().
trim
())
*
pixels_per_meter
);
Cameras
.
insertElementAt
(
camera
,
index
++);
}
is
.
close
();
}
catch
(
Throwable
th
)
{
MyDialog
(
"GetCameras"
,
"Failed to get camera list from server"
);
th
.
printStackTrace
();
return
false
;
}
return
true
;
}
/*
* Send all destinations into the web server.
*/
...
...
@@ -1062,7 +1346,7 @@ public class RoboTrack extends JApplet {
// Its a POST, so no leading "?" for the URL arguments.
String
urlstring
=
"fromapplet=1"
+
"nocookieuid="
+
"
&
nocookieuid="
+
URLEncoder
.
encode
(
uid
)
+
"&nocookieauth="
+
URLEncoder
.
encode
(
auth
);
...
...
@@ -1126,11 +1410,7 @@ public class RoboTrack extends JApplet {
input
.
close
();
if
(
str
.
length
()
>
0
)
{
System
.
out
.
println
(
str
);
JOptionPane
.
showMessageDialog
(
getContentPane
(),
str
,
"Submit Failed"
,
JOptionPane
.
ERROR_MESSAGE
);
MyDialog
(
"Setdest Submission Failed"
,
str
);
}
}
catch
(
Throwable
th
)
...
...
@@ -1140,15 +1420,25 @@ public class RoboTrack extends JApplet {
return
true
;
}
/*
* Utility function to pop up a dialog box.
*/
public
void
MyDialog
(
String
title
,
String
msg
)
{
System
.
out
.
println
(
title
+
" - "
+
msg
);
JOptionPane
.
showMessageDialog
(
getContentPane
(),
msg
,
title
,
JOptionPane
.
ERROR_MESSAGE
);
}
public
static
void
main
(
String
argv
[])
{
final
RoboTrack
robomap
=
new
RoboTrack
();
try
{
URL
url
=
new
URL
(
"file://robots-4.jpg"
);
robomap
.
init
();
robomap
.
init
(
true
);
robomap
.
is
=
System
.
in
;
robomap
.
floorimage
=
robomap
.
getImage
(
url
);
robomap
.
shelled
=
true
;
robomap
.
uid
=
"stoller"
;
robomap
.
auth
=
"xyz"
;
}
...
...
www/robotrack/cameras.php3
0 → 100644
View file @
194773ba
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2002, 2004, 2005 University of Utah and the Flux Group.
# All rights reserved.
#
chdir
(
".."
);
include
(
"defs.php3"
);
#
# Only known and logged in users can watch LEDs
#
$uid
=
GETLOGIN
();
LOGGEDINORDIE
(
$uid
);
#
# One robot map right now ...
#
$building
=
"MEB-ROBOTS"
;
$floor
=
4
;
# Initial goo.
header
(
"Content-Type: text/plain"
);
header
(
"Expires: Mon, 26 Jul 1997 05:00:00 GMT"
);
header
(
"Cache-Control: no-cache, must-revalidate"
);
header
(
"Pragma: no-cache"
);
flush
();
#
# Clean up when the remote user disconnects
#
function
SPEWCLEANUP
()
{
exit
(
0
);
}
register_shutdown_function
(
"SPEWCLEANUP"
);
# Get the obstacle information.
$query_result
=
DBQueryFatal
(
"select * from cameras "
.
"where building='
$building
' and floor='
$floor
'"
);
while
(
$row
=
mysql_fetch_array
(
$query_result
))
{
$name
=
$row
[
"name"
];
$x1
=
$row
[
"loc_x"
];
$y1
=
$row
[
"loc_y"
];
$x2
=
$x1
+
$row
[
"width"
];
$y2
=
$y1
+
$row
[
"height"
];
echo
"
$name
,
$x1
,
$y1
,
$x2
,
$y2
\n
"
;
}
?>
www/robotrack/obstacles.php3
0 → 100644
View file @
194773ba
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2002, 2004, 2005 University of Utah and the Flux Group.
# All rights reserved.
#
chdir
(
".."
);
include
(
"defs.php3"
);
#
# Only known and logged in users can watch LEDs
#
$uid
=
GETLOGIN
();
LOGGEDINORDIE
(
$uid
);
#
# One robot map right now ...
#
$building
=
"MEB-ROBOTS"
;
$floor
=
4
;
# Initial goo.
header
(
"Content-Type: text/plain"
);
header
(
"Expires: Mon, 26 Jul 1997 05:00:00 GMT"
);
header
(
"Cache-Control: no-cache, must-revalidate"
);
header
(
"Pragma: no-cache"
);
flush
();
#
# Clean up when the remote user disconnects
#
function
SPEWCLEANUP
()
{
exit
(
0
);
}
register_shutdown_function
(
"SPEWCLEANUP"
);
#
# Get the obstacle information. This stuff is in pixels, but we want to
# always send meters to the applet.
#
$query_result
=
DBQueryFatal
(
"select o.*,f.pixels_per_meter from obstacles as o "
.
"left join floorimages as f on "
.
" o.building=f.building and o.floor=f.floor "
.
"where o.building='
$building
' and o.floor='
$floor
'"
);
while
(
$row
=
mysql_fetch_array
(
$query_result
))
{
$id
=
$row
[
"obstacle_id"
];
$x1
=
$row
[
"x1"
];
$y1
=
$row
[
"y1"
];
$x2
=
$row
[
"x2"
];
$y2
=
$row
[
"y2"
];
$desc
=
$row
[
"description"
];
$ppm
=
$row
[
"pixels_per_meter"
];
if
(
!
isset
(
$desc
))
$desc
=
""
;
$meters_x1
=
sprintf
(
"%.4f"
,
$x1
/
$ppm
);
$meters_y1
=
sprintf
(
"%.4f"
,
$y1
/
$ppm
);
$meters_x2
=
sprintf
(
"%.4f"
,
$x2
/
$ppm
);
$meters_y2
=
sprintf
(
"%.4f"
,
$y2
/
$ppm
);
echo
"
$id
,
$meters_x1
,
$meters_y1
,
$meters_x2
,
$meters_y2
,
$desc
\n
"
;
}
?>
www/robotrack/robotrack.php3
View file @
194773ba
...
...
@@ -77,7 +77,7 @@ if (!preg_match("/^\/tmp\/([-\w]+)$/", $prefix, $matches)) {
}
$uniqueid
=
$matches
[
1
];
$perl_args
=
"-o
$prefix
-t -z -n -x -y -f
$floor
$building
"
;
$perl_args
=
"-o
$prefix
-t -z -n -x
-v
-y -f
$floor
$building
"
;
$retval
=
SUEXEC
(
$uid
,
"nobody"
,
"webfloormap
$perl_args
"
,
SUEXEC_ACTION_IGNORE
);
...
...
@@ -122,7 +122,10 @@ echo "<br>
moves (start the robots on their way), or cancel the moves.
<li> Only one move per robot at a time.
<li> To change just the orientation (no drag), edit the destination
orientation column in the table.
orientation column in the table.
<li> A robot destination must not overlap an obstacle (shaded area,
blue border), and it must be fully within the field of view of at
least one camera (orange boxes).
</ul>
<blockquote><blockquote>
\n
"
;
...
...
www/robotrack/tracker.jar
View file @
194773ba
No preview for this file type
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment