Commit 6f545cf0 authored by Timothy Stack's avatar Timothy Stack

Some more robot integration.

	* event/lib/event.h, event/lib/event.c: Add some
	event_notification creation functions that get used in
	event-sched.

	* event/sched/event-sched.c, event/sched/rpc.h,
	event/sched/rpc.cc: Sync the start of event time with the
	robots reaching their initial positions.  This is done by
	creating a master event-sequence that takes care of sending
	the SETDEST events and then starting the Simulator timeline.

	* mote/tbuisp.in: Use node_reboot instead of ssh'ing in.

	* robots/GNUmakefile.in: Don't build tbsetdest if ulsshxmlrpcpp is
	not available.

	* robots/emc/loclistener.in: Clear the destination values for a
	node when it reaches its destination.

	* robots/primotion/garcia-pilot.cc,
	robots/primotion/pilotClient.cc: Some cleanup and debugging.

	* robots/primotion/wheelManager.cc: Check the rear sensors for
	obstructions and then decide which way to pivot.

	* robots/rmcd/pilotConnection.h, robots/rmcd/pilotConnection.c,
	robots/rmcd/rclip.h: Even more tweaking.

	* robots/tbsetdest/tbsetdest.cc: Don't generate points that are
	outside the camera bounds or inside an obstacle.

	* robots/vmcd/visionTrack.c, robots/vmcd/vmcd.h,
	robots/vmcd/vmcd.c:  Add more debugging output.

	* tbsetup/os_setup.in: Removed the robot hack used when deciding
	which nodes to reconfig/reboot.  Added a robot hack to avoid
	rebooting a robot whose mote is being os_load'd, since it would
	interrupt tbuisp which does the reboot anyways.  Also fixed a
	small typo.

	* tbsetup/ns2ir/node.tcl, tbsetup/ns2ir/sim.tcl.in: Oops, forgot
	to convert degrees to radians.

	* tbsetup/ns2ir/topography.tcl: When checking for node destination
	points in obstacles, include the implicit exclusion zone.

	* tmcd/common/bootsubnodes: Add empty "mote" case.

	* tmcd/linux-sg/GNUmakefile.in: Make some of the /etc subdirs when
	doing the install.

	* tmcd/linux-sg/rc.stargate: Start garcia-pilot.

	* vis/floormap.in: Add options for showing the camera bounds,
	obstacle exclusion zones, and displaying vnames instead of pnames.

	* www/ledpipe.php3: Finally figured out how to use a socket
	instead of popening a perl script.

	* www/robotmap.php3: Add checkboxes for displaying/not displaying
	the camera bounds and obstacle exclusion zones.  Add a legend
	showing what actual vs. destination points are.  Pass pid/eid
	through to vis/floormap if it is given.

	* www/showexp.php3: Add a "Robot Map" link to experiments that
	have allocated garcias.

	* www/floormap/map_legend_node.gif,
	www/floormap/map_legend_node_dst.gif: Icons used by the robot map
	legend.

	* www/floormap/robots-4.jpg: Added an obstacle around the entryway
	so people are slightly less likely to trip over the robots.  Added
	a coordinate system legend to the top left corner.

	* www/tutorial/mobilewireless.php3: Add links to David's movie of
	the robot making its way around the pillar.

	* www/tutorial/robot_anim.gif: A nifty gifanim clip of the robot
	movie.

	* xmlrpc/emulabserver.py.in: Pull the camera data from the DB,
	instead of returning hardcoded stuff.
parent e333515f
......@@ -1750,10 +1750,14 @@ int event_arg_dup(char *args, char *key, char **value_out)
return retval;
}
int event_do_v(event_handle_t handle, ea_tag_t tag, va_list args)
event_notification_t event_notification_create_v(event_handle_t handle,
struct timeval **when_out,
ea_tag_t tag,
va_list args)
{
event_notification_t retval = NULL;
struct timeval *when = NULL;
address_tuple_t tuple;
int retval = 0;
if ((tuple = address_tuple_alloc()) == NULL) {
ERROR("could not allocate address tuple");
......@@ -1762,8 +1766,6 @@ int event_do_v(event_handle_t handle, ea_tag_t tag, va_list args)
else {
char *arg_name, *event_args, *event_args_cursor;
char event_args_buffer[1024] = "";
struct timeval *when = NULL;
event_notification_t en;
event_args = event_args_buffer;
event_args_cursor = event_args_buffer;
......@@ -1829,29 +1831,64 @@ int event_do_v(event_handle_t handle, ea_tag_t tag, va_list args)
tag = va_arg(args, ea_tag_t);
}
if ((en = event_notification_alloc(handle, tuple)) == NULL) {
if ((retval = event_notification_alloc(handle,
tuple)) == NULL) {
ERROR("could not allocate notification");
errno = ENOMEM;
}
else {
struct timeval tv;
if (when == NULL) {
when = &tv;
gettimeofday(when, NULL);
}
if (strlen(event_args) > 0) {
event_notification_set_arguments(handle,
en,
retval,
event_args);
}
retval = event_schedule(handle, en, when);
event_notification_free(handle, en);
en = NULL;
}
address_tuple_free(tuple);
tuple = NULL;
}
if (when_out != NULL)
*when_out = when;
return retval;
}
event_notification_t event_notification_create(event_handle_t handle,
ea_tag_t tag,
...)
{
event_notification_t retval;
va_list args;
va_start(args, tag);
retval = event_notification_create_v(handle, NULL, tag, args);
va_end(args);
return retval;
}
int event_do_v(event_handle_t handle, ea_tag_t tag, va_list args)
{
event_notification_t en;
struct timeval *when;
int retval = -1;
if ((en = event_notification_create_v(handle, &when,
tag, args)) == NULL) {
ERROR("could not allocate notification");
errno = ENOMEM;
}
else {
struct timeval tv;
if (when == NULL) {
when = &tv;
gettimeofday(when, NULL);
}
retval = event_schedule(handle, en, when);
event_notification_free(handle, en);
en = NULL;
}
return retval;
}
......
......@@ -243,6 +243,13 @@ typedef enum {
EA_When,
} ea_tag_t;
event_notification_t event_notification_create_v(event_handle_t handle,
struct timeval **when_out,
ea_tag_t tag,
va_list args);
event_notification_t event_notification_create(event_handle_t handle,
ea_tag_t tag,
...);
int event_do_v(event_handle_t handle, ea_tag_t tag, va_list args);
int event_do(event_handle_t handle, ea_tag_t tag, ...);
......
......@@ -74,6 +74,11 @@ static pid_t emcd_pid;
static pid_t vmcd_pid;
static pid_t rmcd_pid;
static struct agent ns_sequence_agent;
static timeline_agent_t ns_sequence;
static struct agent ns_timeline_agent;
static timeline_agent_t ns_timeline;
static void sigpass(int sig)
{
kill(emcd_pid, sig);
......@@ -234,6 +239,34 @@ main(int argc, char *argv[])
fatal("could not register with event system");
}
ns_sequence = create_timeline_agent(TA_SEQUENCE);
ns_sequence->ta_local_agent.la_link.ln_Name = ns_sequence_agent.name;
ns_sequence->ta_local_agent.la_handle = handle;
ns_sequence->ta_local_agent.la_agent = &ns_sequence_agent;
ns_sequence_agent.link.ln_Name = ns_sequence_agent.name;
strcpy(ns_sequence_agent.name, "__ns_sequence");
strcpy(ns_sequence_agent.nodeid, "*");
strcpy(ns_sequence_agent.vnode, "*");
strcpy(ns_sequence_agent.objtype, TBDB_OBJECTTYPE_SEQUENCE);
strcpy(ns_sequence_agent.ipaddr, "*");
ns_sequence_agent.handler = &ns_sequence->ta_local_agent;
lnAddTail(&sequences, &ns_sequence->ta_local_agent.la_link);
lnAddTail(&agents, &ns_sequence_agent.link);
ns_timeline = create_timeline_agent(TA_TIMELINE);
ns_timeline->ta_local_agent.la_link.ln_Name = ns_timeline_agent.name;
ns_timeline->ta_local_agent.la_handle = handle;
ns_timeline->ta_local_agent.la_agent = &ns_timeline_agent;
ns_timeline_agent.link.ln_Name = ns_timeline_agent.name;
strcpy(ns_timeline_agent.name, "__ns_timeline");
strcpy(ns_timeline_agent.nodeid, "*");
strcpy(ns_timeline_agent.vnode, "*");
strcpy(ns_timeline_agent.objtype, TBDB_OBJECTTYPE_TIMELINE);
strcpy(ns_timeline_agent.ipaddr, "*");
ns_timeline_agent.handler = &ns_timeline->ta_local_agent;
lnAddTail(&timelines, &ns_timeline->ta_local_agent.la_link);
lnAddTail(&agents, &ns_timeline_agent.link);
/*
* Construct an address tuple for event subscription. We set the
* scheduler flag to indicate we want to capture those notifications.
......@@ -255,7 +288,7 @@ main(int argc, char *argv[])
if (RPC_agentlist(handle, pid, eid))
fatal("Could not get agentlist from RPC server\n");
if (RPC_waitforrobots(pid, eid))
if (RPC_waitforrobots(handle, pid, eid))
fatal("waitforrobots: RPC failed!");
if (access("tbdata/emcd.config", R_OK) == 0) {
......@@ -302,7 +335,7 @@ main(int argc, char *argv[])
case 0:
execlp("rmcd",
"rmcd",
"-d",
"-dd",
"-l",
"logs/rmcd.log",
"-U",
......@@ -884,6 +917,9 @@ AddEvent(event_handle_t handle, address_tuple_t tuple, long basetime,
return -1;
}
}
else {
ta = ns_timeline;
}
tuple->host = agentp->ipaddr;
tuple->objname = objname;
......@@ -938,6 +974,45 @@ AddEvent(event_handle_t handle, address_tuple_t tuple, long basetime,
return 0;
}
int
AddRobot(event_handle_t handle,
struct agent *agent,
double init_x,
double init_y,
double init_o)
{
sched_event_t se;
int retval = 0;
assert(agent != NULL);
se.agent.s = agent;
se.notification = event_notification_create(
handle,
EA_Experiment, pideid,
EA_Type, TBDB_OBJECTTYPE_NODE,
EA_Event, TBDB_EVENTTYPE_SETDEST,
EA_Name, agent->name,
EA_ArgFloat, "X", init_x,
EA_ArgFloat, "Y", init_y,
EA_ArgFloat, "ORIENTATION", init_o,
EA_TAG_DONE);
event_notification_put_int32(handle,
se.notification,
"TOKEN",
next_token);
next_token += 1;
memset(&se.time, 0, sizeof(se.time));
se.length = 1;
se.flags = SEF_SENDS_COMPLETE | SEF_SINGLE_HANDLER;
sched_event_prepare(handle, &se);
timeline_agent_append(ns_sequence, &se);
return retval;
}
/*
* Get the static event list from the DB and schedule according to
* the relative time stamps.
......@@ -952,24 +1027,6 @@ get_static_events(event_handle_t handle)
event_notification_t notification;
sched_event_t event;
if (RPC_grouplist(handle, pid, eid)) {
error("Could not get grouplist from RPC server\n");
return -1;
}
if (debug) {
struct agent *agentp = (struct agent *)agents.lh_Head;
while (agentp->link.ln_Succ) {
info("Agent: %15s %10s %10s %8s %16s\n",
agentp->name, agentp->objtype,
agentp->vnode, agentp->nodeid,
agentp->ipaddr);
agentp = (struct agent *)agentp->link.ln_Succ;
}
}
/*
* Construct an address tuple for the notifications. We can reuse
* the same one over and over since the data is copied out.
......@@ -981,20 +1038,6 @@ get_static_events(event_handle_t handle)
}
tuple->expt = pideid;
sprintf(pideid, "%s/%s", pid, eid);
gettimeofday(&now, NULL);
info(" Getting event stream at: %lu:%d\n", now.tv_sec, now.tv_usec);
/*
* XXX Pad the start time out a bit to give this code a chance to run.
*/
basetime = now.tv_sec + 3;
if (RPC_eventlist(pid, eid, handle, tuple, basetime)) {
error("Could not get eventlist from RPC server\n");
return -1;
}
/*
* Generate a TIME starts message.
*/
......@@ -1010,18 +1053,85 @@ get_static_events(event_handle_t handle)
}
event_notification_insert_hmac(handle, notification);
event.notification = notification;
event.time.tv_sec = basetime;
event.time.tv_sec = 0;
event.time.tv_usec = 0;
event.agent.s = NULL;
event.length = 1;
event.flags = 0;
sched_event_enqueue(event);
timeline_agent_append(ns_sequence, &event);
event.agent.s = primary_simulator_agent->sa_local_agent.la_agent;
event.notification = event_notification_create(
handle,
EA_Experiment, pideid,
EA_Type, TBDB_OBJECTTYPE_SIMULATOR,
EA_Event, TBDB_EVENTTYPE_LOG,
EA_Name, event.agent.s->name,
EA_Arguments, "Time started",
EA_TAG_DONE);
memset(&event.time, 0, sizeof(event.time));
event.length = 1;
event.flags = SEF_SINGLE_HANDLER;
sched_event_prepare(handle, &event);
timeline_agent_append(ns_sequence, &event);
info("TIME STARTS will be sent at: %lu:%d\n", now.tv_sec, now.tv_usec);
event.agent.s = &ns_timeline_agent;
event.notification = event_notification_create(
handle,
EA_Experiment, pideid,
EA_Type, TBDB_OBJECTTYPE_TIMELINE,
EA_Event, TBDB_EVENTTYPE_START,
EA_Name, ns_timeline_agent.name,
EA_TAG_DONE);
memset(&event.time, 0, sizeof(event.time));
event.length = 1;
event.flags = SEF_SENDS_COMPLETE | SEF_SINGLE_HANDLER;
sched_event_prepare(handle, &event);
timeline_agent_append(ns_sequence, &event);
if (RPC_grouplist(handle, pid, eid)) {
error("Could not get grouplist from RPC server\n");
return -1;
}
if (debug) {
struct agent *agentp = (struct agent *)agents.lh_Head;
while (agentp->link.ln_Succ) {
info("Agent: %15s %10s %10s %8s %16s\n",
agentp->name, agentp->objtype,
agentp->vnode, agentp->nodeid,
agentp->ipaddr);
agentp = (struct agent *)agentp->link.ln_Succ;
}
}
sprintf(pideid, "%s/%s", pid, eid);
gettimeofday(&now, NULL);
info("The time is now: %lu:%d\n", now.tv_sec, now.tv_usec);
info(" Getting event stream at: %lu:%d\n", now.tv_sec, now.tv_usec);
/*
* XXX Pad the start time out a bit to give this code a chance to run.
*/
basetime = now.tv_sec + 3;
if (RPC_eventlist(pid, eid, handle, tuple, basetime)) {
error("Could not get eventlist from RPC server\n");
return -1;
}
event_do(handle,
EA_Experiment, pideid,
EA_Type, TBDB_OBJECTTYPE_SEQUENCE,
EA_Event, TBDB_EVENTTYPE_START,
EA_Name, ns_sequence_agent.name,
EA_TAG_DONE);
return 0;
}
......
......@@ -381,7 +381,7 @@ RPC_obstaclelist(FILE *emcd_config, char *area)
}
int
RPC_waitforrobots(char *pid, char *eid)
RPC_waitforrobots(event_handle_t handle, char *pid, char *eid)
{
emulab::EmulabResponse er;
int lpc, rc, retval = 0;
......@@ -408,6 +408,8 @@ RPC_waitforrobots(char *pid, char *eid)
if (locs.size() == 0)
return 0;
info("info: waiting for robots\n");
if ((emcd_config = fopen("tbdata/emcd.config", "w")) == NULL) {
fprintf(stderr, "Cannot create emcd.config!\n");
......@@ -433,7 +435,6 @@ RPC_waitforrobots(char *pid, char *eid)
return -1;
}
#if 0
else if ((rc = RPC_invoke(
"node.statewait",
&ner,
......@@ -445,7 +446,6 @@ RPC_waitforrobots(char *pid, char *eid)
return -1;
}
#endif
else {
fprintf(emcd_config,
"robot %s %d %s %f %f %f %s\n",
......@@ -457,6 +457,8 @@ RPC_waitforrobots(char *pid, char *eid)
orientation,
agent->name);
buildings.insert(bldg.getString());
AddRobot(handle, agent, x, y, orientation);
}
}
......
......@@ -57,7 +57,7 @@ int RPC_grab(void);
void RPC_drop(void);
int RPC_exppath(char *pid, char *eid, char *path_out, size_t path_size);
int RPC_waitforrobots(char *pid, char *eid);
int RPC_waitforrobots(event_handle_t handle, char *pid, char *eid);
int RPC_waitforactive(char *pid, char *eid);
int RPC_agentlist(event_handle_t handle, char *pid, char *eid);
int RPC_grouplist(event_handle_t handle, char *pid, char *eid);
......@@ -76,6 +76,12 @@ extern int AddEvent(event_handle_t handle, address_tuple_t tuple,
char *exidx, char *ftime, char *objname, char *exargs,
char *objtype, char *evttype, char *parent);
extern int AddRobot(event_handle_t handle,
struct agent *agent,
double init_x,
double init_y,
double init_orientation);
#ifdef __cplusplus
}
#endif
......
......@@ -23,7 +23,13 @@ else
EMCDIR=
endif
SUBDIRS = tbsetdest $(MEZZDIR) mtp $(EMCDIR) vmcd primotion rmcd
ifeq ($(HAVE_ULXMLRPCPP),yes)
TBSETDESTDIR=tbsetdest
else
TBSETDESTDIR=
endif
SUBDIRS = $(TBSETDESTDIR) $(MEZZDIR) mtp $(EMCDIR) vmcd primotion rmcd
all: robomonitord all-subdirs
client: client-subdirs
......
......@@ -28,6 +28,6 @@ struct vmc_client {
#define EMC_SERVER_PORT 2525
#define EMC_UPDATE_HZ (2 * 1000)
#define EMC_UPDATE_HZ (1500)
#endif
......@@ -88,6 +88,15 @@ class LocationInfoUpdater(EventClient):
else:
node_id = res[0][0]
pass
if event.getEventType() == "COMPLETE":
DBQueryFatal("UPDATE nodes SET "
"destination_x=NULL,"
"destination_y=NULL,"
"destination_orientation=NULL "
"WHERE node_id=%s",
(node_id,))
return
update = {}
for arg in event.getArguments().split():
......@@ -160,7 +169,14 @@ liu = LocationInfoUpdater(server=server, port=port)
at = address_tuple()
at.objtype = "NODE"
at.eventtype = "MODIFY,SETDEST"
at.eventtype = "SETDEST,MODIFY"
liu.subscribe(at)
at = address_tuple()
at.objtype = "NODE"
at.eventtype = "COMPLETE"
at.scheduler = 1
liu.subscribe(at)
......
......@@ -106,12 +106,14 @@ static void sigpanic(int signum)
snprintf(msg, sizeof(msg), "panic: %d; reexec'ing\n", signum);
write(1, msg, strlen(msg));
#if 0
execve(reexec_argv[0], reexec_argv, environ);
snprintf(msg, sizeof(msg), "reexec failed %s\n", strerror(errno));
write(1, msg, strlen(msg));
#endif
exit(1);
abort();
}
/**
......@@ -190,21 +192,19 @@ int main(int argc, char *argv[])
if (!debug) {
/* Become a daemon */
daemon(1, 0);
}
if (logfile) {
int logfd;
if ((logfd = open(logfile,
O_CREAT|O_WRONLY|O_APPEND,
0644)) != -1) {
dup2(logfd, 1);
dup2(logfd, 2);
if (logfd > 2)
close(logfd);
}
if (logfile) {
int logfd;
if ((logfd = open(logfile, O_CREAT|O_WRONLY|O_APPEND, 0644)) != -1) {
dup2(logfd, 1);
dup2(logfd, 2);
if (logfd > 2)
close(logfd);
}
}
if (pidfile) {
FILE *fp;
......@@ -350,12 +350,6 @@ int main(int argc, char *argv[])
struct timeval tv_zero = { 0, 0 };
int rc;
if (debug == 3) {
int *i = 0;
*i = 1;
}
/* Poll the file descriptors, don't block */
rc = select(FD_SETSIZE,
&rreadyfds,
......@@ -450,7 +444,7 @@ int main(int argc, char *argv[])
garcia.handleCallbacks(50);
aIO_GetMSTicks(ioRef, &now, NULL);
} while (looping && db.update(now));
garcia.flushQueuedBehaviors();
garcia.handleCallbacks(1000);
......@@ -459,7 +453,7 @@ int main(int argc, char *argv[])
aIO_ReleaseLibRef(ioRef, &err);
if (batterylog) {
if (batterylog != NULL) {
fclose(batterylog);
batterylog = NULL;
}
......
......@@ -87,6 +87,11 @@ void pilotMoveCallback::call(int status)
MA_CommandID, this->command_id,
MA_TAG_DONE);
if (debug > 1) {
fprintf(stderr, "debug: sending update\n");
mtp_print_packet(stderr, &mp);
}
for (i = this->notify_list.begin(); i != this->notify_list.end(); i++) {
pilotClient *pc = *i;
......
......@@ -174,7 +174,7 @@ wheelManager::~wheelManager()
acpObject *wheelManager::createPivot(float angle, wmCallback *callback)
{
acpObject *retval = NULL;
assert(this->invariant());
/* First, reduce to a single rotation, */
......@@ -239,8 +239,9 @@ acpObject *wheelManager::createMove(float distance, wmCallback *callback)
void wheelManager::setDestination(float x, float y, wmCallback *callback)
{
struct mtp_garcia_telemetry *mgt;
float diff, angle, distance;
acpObject *move, *pivot;
float angle, distance;
angle = atan2f(y, x);
distance = hypot(x, y);
......@@ -257,6 +258,24 @@ void wheelManager::setDestination(float x, float y, wmCallback *callback)
distance = -distance;
}
mgt = this->wm_dashboard->getTelemetry();
diff = fabsf(mgt->rear_ranger_left - mgt->rear_ranger_right);
if (diff > 0.08f) {
if ((mgt->rear_ranger_right == 0.0f) ||
(mgt->rear_ranger_left < mgt->rear_ranger_right)) {
if (angle < 0.0f) {
angle += M_PI;
distance = -distance;
}
}
else {
if (angle > 0.0f) {
angle -= M_PI;
distance = -distance;
}
}
}
if ((move = this->createMove(distance, callback)) == NULL) {
/* Skipping everything. */
if (callback != NULL) {
......
This diff is collapsed.
......@@ -27,6 +27,7 @@ enum {
PCB_WAYPOINT,
PCB_CONTACT,
PCB_WIGGLE_REVERSE,
PCB_IN_PROGRESS,
};
enum {
......@@ -36,6 +37,7 @@ enum {
PCF_WAYPOINT = (1L << PCB_WAYPOINT),
PCF_CONTACT = (1L << PCB_CONTACT),
PCF_WIGGLE_REVERSE = (1L << PCB_WIGGLE_REVERSE),
PCF_IN_PROGRESS = (1L << PCB_IN_PROGRESS),
};
struct pilot_connection {
......
......@@ -19,6 +19,8 @@ enum {
RCF_BOTTOM = (1L << RCB_BOTTOM),
RCF_RIGHT = (1L << RCB_RIGHT),
RCF_LEFT = (1L << RCB_LEFT),
RCF_ALL = (RCF_TOP|RCF_BOTTOM|RCF_LEFT|RCF_RIGHT)
};
typedef unsigned long rc_code_t;
......
......@@ -103,6 +103,7 @@ void show_diffs(void);
void show_routes(void);
void show_counters(void);
const double OBSTACLE_BUFFER = 0.25;
/* ======================================================================
Global Variables
......@@ -142,7 +143,9 @@ u_int32_t *D2 = 0;
ulxr::SSLConnection *xmlrpc_conn;
ulxr::Protocol *xmlrpc_proto;
emulab::EmulabResponse cameras_er, obstacles_er;
ulxr::Array cameras;
ulxr::Array obstacles;
/* ======================================================================
Random Number Generation
......@@ -346,20 +349,27 @@ main(int argc, char **argv)
init();
emulab::ServerProxy proxy(xmlrpc_proto, false, TBROOT);
emulab::EmulabResponse er;
er = proxy.invoke("emulab.vision_config",
emulab::SPA_String, "area", AREA_NAME,
emulab::SPA_TAG_DONE);
cameras = (ulxr::Array)er.getValue();
cameras_er = proxy.
invoke("emulab.vision_config",
emulab::SPA_String, "area", AREA_NAME,
emulab::SPA_TAG_DONE);
obstacles_er = proxy.
invoke("emulab.obstacle_config",
emulab::SPA_String, "area", AREA_NAME,
emulab::SPA_String, "units", "meters",
emulab::SPA_TAG_DONE);
cameras = (ulxr::Array)cameras_er.getValue();
for (lpc = 0; lpc < cameras.size(); lpc++) {
double x, y, width, height;
ulxr::Struct attr;
attr = cameras.getItem(lpc);
x = ((ulxr::Double)attr.getMember("x")).getDouble();
y = ((ulxr::Double)attr.getMember("y")).getDouble();
x = ((ulxr::Double)attr.getMember("loc_x")).
getDouble();
y = ((ulxr::Double)attr.getMember("loc_y")).
getDouble();
width = ((ulxr::Double)attr.getMember("width")).
getDouble();
height = ((ulxr::Double)attr.getMember("height")).
......@@ -375,6 +385,8 @@ main(int argc, char **argv)
MAXY = (y + height);
}
obstacles = (ulxr::Array)obstacles_er.getValue();
init2();
}
catch(ulxr::Exception &ex)
......@@ -618,22 +630,72 @@ Node::Node()
}
static bool check_position(double rx, double ry)
{
unsigned int lpc, camera_hit = 0;
bool retval = 1;
for (lpc = 0; lpc < cameras.size(); lpc++) {
double x, y, width, height;
ulxr::Struct attr;