VR-Forces 4.1.1 Class Documentation
Remote Control Text Interface

This class allows the user to type in commands that will be parsed and used to supply information to the remote controller.


Header file:

/*******************************************************************************
** Copyright (c) 2002 MAK Technologies, Inc.
** All rights reserved.
*******************************************************************************/
/*******************************************************************************
** $RCSfile: textIf.h,v $ $Revision: 1.13 $ $State: Exp $
*******************************************************************************/
#ifndef DtTextInterface_H_
#define DtTextInterface_H_
#include <vlutil/vlUtil.h>
//This class provides a text interface for controlling VR-Forces over the network.
//This interface currently supports the following actions:
//
//1. load <filename>
// load a scenario file
//2. save <filename>
// save the current scenario
//3. new <db filename>
// create a new scenario
//4. close
// close the current scenario
//5. rewind
// rewind the current scenario to its start state
//6. run
// sends a message interface request to run the current scenario
//6a. simrun
// sends a sim mgmt start PDU to run the current scenario
//7. simpause
// sends a sim mgmt stop PDU to pause the current scenario
//7a. pause
// sends a sim mgmt pause request to pause the current scenario
//8. list
// list all the backends that are currently running
//9. create [ waypoint | route | tank | aggregate]
// create a VR-Forces waypoint, route, tank, or tank aggregate
//10. delete [ <object_name> | <object_id> ]
// delete a VR-Forces object by name or by object ID
//11. set [ plan | label | location | fuel | target | restore ]
// set a VR-Forces object attribute
//12. task [ patrolRoute | moveToPoint | follow | wait ]
// task a VR-Forces entity
//13. aggregate "name1" "name2" "name3"
// aggregate 3 VR-Forces entities together
//14. quit
// quit the application
{
public:
//constructor
//destructor
virtual ~DtTextInterface();
//Process entered text
void readStdin();
//Set/Get time to quit
virtual void setTimeToQuit(bool yesNo);
virtual bool timeToQuit() const;
//Get remote vrf controller pointer
public:
//Functions for parsing command strings and calling
//the corresponding methods on DtVrfRemoteController.
virtual void createWaypoint(char* str);
virtual void createRoute(char* str);
virtual void createTank(char* str);
virtual void createAggregate(char* str);
virtual void setPlan(char* str);
virtual void setLabel(char* str);
virtual void setLocation(char* str);
virtual void setFuel(char* str);
virtual void setTarget(char* str);
virtual void setRestore(char* str);
virtual void patrolRoute(char* str);
virtual void moveToPoint(char* str);
virtual void follow(char* str);
virtual void wait(char* str);
virtual void bigRoute(int iPoints);
public:
//-------------------------------------------------------
//Text callback functions
//-------------------------------------------------------
//Called in response to "list"
static void listCmd(char* s, DtTextInterface* a);
//Called in response to "load"
static void loadCmd(char* s, DtTextInterface* a);
//Called by DtVrfRemoteController::loadScenario when back-ends are missing
static bool missingBackends(DtBackendMap* map, void* usr);
//Called in response to "new"
static void newCmd(char* s, DtTextInterface* a);
//Called in response to "save"
static void saveCmd(char* s, DtTextInterface* a);
//Called in response to "create"
static void createCmd(char* s, DtTextInterface* a);
//Called in response to "set"
static void setCmd(char* s, DtTextInterface* a);
//Called in response to "task"
static void taskCmd(char* s, DtTextInterface* a);
//Called in response to "aggregate"
static void aggregateCmd(char* s, DtTextInterface* a);
//Called in response to "delete"
static void deleteCmd(char* s, DtTextInterface* a);
//Called in response to "close"
static void closeCmd(char* s, DtTextInterface* a);
//Called in response to "monitor"
static void monitorResourcesCmd(char* s, DtTextInterface* a);
//Called in response to "unmonitor"
static void removeMonitorResourcesCmd(char* s, DtTextInterface* a);
//Called in response to "rewind"
static void rewindCmd(char* s, DtTextInterface* a);
//Called in response to "run"
static void runCmd(char* s, DtTextInterface* a);
//Called in response to "pause"
static void pauseCmd(char* s, DtTextInterface* a);
//Called in response to "simrun"
static void simrunCmd(char* s, DtTextInterface* a);
//Called in response to "simpause"
static void simpauseCmd(char* s, DtTextInterface* a);
//Called in response to "quit" or "q"
static void quitCmd(char* s, DtTextInterface* a);
//Called in response to "help" or "?" or "h"
static void helpCmd(char* s, DtTextInterface* a);
//Called in response to "help" or "?" or "h"
static void bigRouteCmd(char* s, DtTextInterface* a);
//-------------------------------------------------------
//DtVrfRemoteController callback functions
//-------------------------------------------------------
//Backend arrival/departure callbacks
static void backendAddedCb(const DtSimulationAddress& addr, void* usr);
static void backendRemovedCb(const DtSimulationAddress& addr, void* usr);
//Backend loaded/saved callbacks
static void backendLoadedCb(const DtSimulationAddress& addr, void* usr);
static void backendSavedCb(const DtSimulationAddress& addr,
DtSaveResult result, void* usr);
//Scenario loaded/saved callbacks
static void ScenarioLoadedCb(void* usr);
static void ScenarioSavedCb(void* usr);
//VR-Forces object created callback
static void vrfObjectCreatedCb(
const DtString& name, const DtEntityIdentifier& id, void* usr);
//Plan callbacks
static void planCb(const DtString& name,
const DtList& stmts, bool append, void* usr);
static void planStmtCb(const DtString& id, DtPlanStatus status, void* usr);
static void planCompleteCb(const DtString& id, void* usr);
//Callback used to process monitor resource responses
static void resourcesProcessedCb(DtSimMessage* msg, void* usr);
//Callback used to receive object console messages from the remote control
//API.
static void objectConsoleMessageCb(const DtEntityIdentifier& id,
int notifyLevel, const DtString& message, void* usr);
protected:
//Present commmand line interface.
void prompt();
//Parse user input, call corresponding function
void processCmd(char *buff);
protected:
DtSelectParam sparam;
static unsigned int theNextAggregateId;
static unsigned int theNextSubordinateId;
private:
};
#endif

Implementation:

/*******************************************************************************
** Copyright (c) 2011 MAK Technologies, Inc.
** All rights reserved.
*******************************************************************************/
#include "textIf.h"
#include <vlutil/vlPrint.h>
#include <vl/hostStructs.h>
#include <vlpi/disEnums.h>
#include "vrfplan/plan.h"
#include "vrfplan/ifStmt.h"
#include <vl/startInter.h>
#include <vl/stopInter.h>
#include <time.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#if DT_HAVE_UNISTD_H
#include <unistd.h>
#endif
#if !WIN32
#include <sys/fcntl.h>
#else
#include <fcntl.h>
#endif
#if WIN32
#include <io.h>
#include <conio.h>
#endif
#if !WIN32
#define UNBLOCK() setBlock(0, 0)
#define RESTORE() setBlock(0, 1)
#else
#define UNBLOCK()
#define RESTORE()
#endif
const char* terrainDir = "..\\userData\\terrains\\";
const char* scenariosDir = "..\\userData\\scenarios\\";
static bool monitorResourcesCallbackAdded = false;
//-------------------------------------------------------
//Initialize command chart
//-------------------------------------------------------
typedef void (*CmdFunc)(char *, DtTextInterface *a);
struct Cmd
{
char *name;
CmdFunc func;
};
Cmd allCmds[] = {
};
int nCmds = DtNUMBER(allCmds);
{
if (!strncmp(s, "create", 6))
{
DtInfo("\n"
"\tcreate waypoint <\"name\"> <p1>\n"
"\tcreate route <\"name\"> <p1 p2 ... pn>\n"
"\tcreate tank <p1>\n"
"\tcreate aggregate <p1>\n"
"\t\twhere px has form x,y,z\n");
}
else if (!strncmp(s, "set", 3))
{
DtInfo("\n"
"\tset plan <\"name\">\n"
"\tset label <objectId> <\"label\">\n"
"\tset location <\"name\"> <pt>\n"
"\tset fuel <\"name\"> <double>\n"
"\tset target <\"name\"> <\"name\">\n"
"\tset restore <\"name\"> \n");
}
else if (!strncmp(s, "task", 4))
{
DtInfo("\n"
"\ttask patrolRoute <\"name\"> <\"route\">\n"
"\ttask moveToPoint <\"name\"> <\"waypoint\">\n"
"\ttask follow <\"name\"> <\"leader\">\n"
"\ttask wait <\"name\"> <time>\n");
}
else if (!strncmp(s, "monitor", 4))
{
DtInfo("\nmonitor <\"resource\" | \"ALL\"> <\"entity name\"> [update time in seconds]\n");
}
else if (!strncmp(s, "unmonitor", 4))
{
DtInfo("\nunmonitor <\"resource\" | \"ALL\"> <\"entity name\">\n");
}
else if (!strncmp(s, "simrun", 4))
{
DtInfo("simrun [site:host]\n");
}
else if (!strncmp(s, "simpause", 4))
{
DtInfo("simpause [site:host]\n");
}
else if (!strncmp(s, "aggregate", 4))
{
DtInfo("\naggregate <name1> <name2> <name3>\n");
}
else
{
DtInfo("\n"
"\tload <\"filename\">\n"
"\tsave <\"filename\">\n"
"\tnew <\"terrain db filename\">\n"
"\tclose\n"
"\trewind\n"
"\trun\n"
"\tpause\n"
"\tsimrun\n"
"\tsimpause\n"
"\tlist\n"
"\tcreate [ waypoint | route | tank | aggregate]\n"
"\tdelete [ <object_name> | <object_id> ]\n"
"\tset [ plan | label | location | fuel | target | restore ]\n"
"\ttask [ patrolRoute | moveToPoint | follow | wait ]\n"
"\taggregate <name1> <name2> <name3>\n"
"\tmonitor <\"resource\" | \"ALL\"> <\"entity name\"> [update time in seconds]\n"
"\tunmonitor <\"resource\" | \"ALL\"> <\"entity name\">\n"
"\thelp <command_name>\n"
"\tquit\n");
}
}
{
a->setTimeToQuit(true);
}
{
int i = 0;
DtInfo("Listing known backends\n");
DtList backends = a->controller()->backends();
for (DtListItem* item = backends.first(); item; item = item->next())
{
DtSimulationAddress* addr = (DtSimulationAddress*) item->data();
DtInfo("\t%d) %s\n", ++i, addr->string());
if (i == 5) DtInfo("\n");
}
DtInfo("Current state: %s\n", DtControlTypeString(
}
{
#if WIN32
str[strlen(str)]='\0';
#else
str[strlen(str)-1]='\0';
#endif
if (!strcmp(str, "")) return;
char *name;
name = strtok(str, "\"");
DtFilename(DtString(scenariosDir) + DtString(name)), missingBackends,
a);
}
void* usr)
{
DtWarn("Cannot load scenario due to missing backends:\n");
DtListItem* item;
for (item = map->first(); item; item = item->next())
{
DtBackendMapEntry* entry = (DtBackendMapEntry*)item->data();
if (entry)
{
DtWarn("\t%s\n", entry->fromAddress().string());
}
}
return false;
}
{
#if WIN32
str[strlen(str)]='\0';
#else
str[strlen(str)-1]='\0';
#endif
int iPoints = 0;
if (strlen(str) == 0)
{
iPoints = 800;
}
else
{
iPoints = atoi(str);
}
a->bigRoute(iPoints);
}
void DtTextInterface::bigRoute(int iPoints)
{
srand(time(NULL));
DtList verts;
for (int i = 0; i < iPoints; i++)
{
verts.add(new DtVector((double)((double)rand() / (double)RAND_MAX) * 2000.,
(double)((double)rand() / (double)RAND_MAX) * 2000., 100.));
}
DtListItem* item = verts.first();
while (item)
{
delete (DtVector*)item->data();
item = item->next();
}
}
{
#if WIN32
str[strlen(str)]='\0';
#else
str[strlen(str)-1]='\0';
#endif
if (!strcmp(str, "")) return;
if (!strstr(str, ".scn"))
strcat(str, ".scn");
char *name;
name = strtok(str, "\"");
DtFilename(DtString(scenariosDir) + DtString(name)));
}
{
a->controller()->rewind();
}
{
}
{
#if WIN32
str[strlen(str)]='\0';
#else
str[strlen(str)-1]='\0';
#endif
if (!strcmp(str, ""))
{
DtInfo("Give me a terrain database, please!\n> ");
}
else
{
char *name;
name = strtok(str, "\"");
DtFilename terrainFilename(DtString(terrainDir) + DtString(name));
a->controller()->newScenario(terrainFilename, terrainFilename);
}
}
{
#if WIN32
str[strlen(str)]='\0';
#else
str[strlen(str)-1]='\0';
#endif
if (!strcmp(str, ""))
{
DtInfo("Create what?!\n");
helpCmd("create", NULL);
}
else if (!strncmp(str, "waypoint", 8))
{
a->createWaypoint(str);
}
else if (!strncmp(str, "route", 5))
{
a->createRoute(str);
}
else if (!strncmp(str, "tank", 4))
{
a->createTank(str);
}
else if (!strncmp(str,"aggregate",9))
{
a->createAggregate(str);
}
}
{
//Let's parse the command string and then call
//the corresponding method on DtVrfRemoteController.
char *point;
point = strtok(&str[9], " ");
if (!point)
{
DtInfo("\tusage: aggregate <geocentric_location>\n");
return;
}
DtVector vec;
sscanf(point, "%lf,%lf,%lf", &vec[0], &vec[1], &vec[2]);
//Here we are creating the indivual parts. We register with the vrfObjectCreatedCb callback because
//we can't add the subordinates to our aggregate until they've actually been created. Timing can be tricky here if the indivual is
//created before the aggregate. In this simple example we create the aggregate entity first then it's subordinates.
//When manaully creating aggregates and their components this timing must be considered. One means is to check if the aggregate has been created
//and if not, keep a list of the individuals and in a callback once the desired aggregate has been created then add them to the aggregate's
//organization.
//Create the aggregate entity at desired position with name "tankPlt"
DtString pltName = "Tank_Plt_" + DtString(theNextAggregateId++);
(void*)myController,
DtEntityType(11, 1, 225, 3, 0, 0, 0), vec,
DtForceFriendly, 0,pltName);
//Now create the individual tanks that will make up this aggregate
DtString subName = "Plt_Sub_";
DtEntityType(1, 1, 225, 1, 1, 3, 0), vec,
DtForceFriendly, 90.0,subName + DtString(theNextSubordinateId++));
//Change the offet from each other to create an intial triangle formation
vec[DtX]+=10;
DtEntityType(1, 1, 225, 1, 1, 3, 0), vec,
DtForceFriendly, 90.0,subName + DtString(theNextSubordinateId++));
vec[DtY]+=10;
DtEntityType(1, 1, 225, 1, 1, 3, 0), vec,
DtForceFriendly, 90.0,subName + DtString(theNextSubordinateId++));
}
{
((DtSimInterfaceMessage*) msg)->interfaceContent();
DtString str;
{
DtInfo("%s\n", str.string());
}
}
{
if (!strcmp(str, ""))
{
DtInfo("Monitor what?!\n");
helpCmd("monitor", NULL);
}
else
{
char *res;
char *entity;
char *time;
char* temp;
int iTime = 10;
res = strtok(str, "\"");
temp = strtok(NULL, "\"");
entity = strtok(NULL, "\"");
time = strtok(NULL, "\"");
req.setObjectName(entity);
if (time)
{
iTime = atoi(time);
}
req.setMonitorPeriod(iTime);
if (strcmp(res, "ALL"))
{
req.addMonitoredItem(res);
}
if (!monitorResourcesCallbackAdded)
{
monitorResourcesCallbackAdded = true;
}
}
}
{
if (!strcmp(str, ""))
{
DtInfo("unmonitor what?!\n");
helpCmd("unmonitor", NULL);
}
else
{
char *res;
char *entity;
char* temp;
res = strtok(str, "\"");
temp = strtok(NULL, "\"");
entity = strtok(NULL, "\"");
temp = strtok(NULL, "\"");
req.setObjectName(entity);
if (strcmp(res, "ALL"))
{
req.addMonitoredItem(res);
}
req.setStopMonitoring(true);
}
}
{
#if WIN32
str[strlen(str)]='\0';
#else
str[strlen(str)-1]='\0';
#endif
if (!strcmp(str, ""))
{
DtInfo("Aggregate what?!\n");
helpCmd("aggregate", NULL);
}
else
{
char *e1, *e2, *e3, *temp;
e1 = strtok(str, "\"");
temp = strtok(NULL, "\"");
e2 = strtok(NULL, "\"");
temp = strtok(NULL, "\"");
e3 = strtok(NULL, "\"");
temp = strtok(NULL, "\"");
DtList entities;
if (e1) entities.add(new DtString(e1));
if (e2) entities.add(new DtString(e2));
if (e3) entities.add(new DtString(e3));
DtEntityType(11, 1, 0, 3, 2, 0, 0),
DtVector(10.0, 10.0, 10.0),
DtForceFriendly, 0.0, &entities);
//empty list of entities
DtListItem* next = NULL;
for (DtListItem* item = entities.first(); item; item = next)
{
next = item->next();
delete (DtString*) entities.remove(item);
}
}
}
{
#if WIN32
str[strlen(str)]='\0';
#else
str[strlen(str)-1]='\0';
#endif
if (!strcmp(str, ""))
{
DtInfo("Set what?!\n");
helpCmd("set", NULL);
}
else if (!strncmp(str, "plan", 4))
{
a->setPlan(str);
}
else if (!strncmp(str, "label", 5))
{
a->setLabel(str);
}
else if (!strncmp(str, "location", 8))
{
a->setLocation(str);
}
else if (!strncmp(str, "fuel", 4))
{
a->setFuel(str);
}
else if (!strncmp(str, "target", 6))
{
a->setTarget(str);
}
else if (!strncmp(str, "restore", 7))
{
a->setRestore(str);
}
}
{
#if WIN32
str[strlen(str)]='\0';
#else
str[strlen(str)-1]='\0';
#endif
if (!strcmp(str, ""))
{
DtInfo("Task what?!\n");
helpCmd("task", NULL);
}
else if (!strncmp(str, "patrolRoute", 11))
{
a->patrolRoute(str);
}
else if (!strncmp(str, "moveToPoint", 11))
{
a->moveToPoint(str);
}
else if (!strncmp(str, "follow", 6))
{
a->follow(str);
}
else if (!strncmp(str, "wait", 4))
{
a->wait(str);
}
}
{
#if WIN32
s[strlen(s)]='\0';
#else
s[strlen(s)-1]='\0';
#endif
if (strchr(s, ':'))
{
a->controller()->deleteObject(DtEntityIdentifier(s));
}
else
{
char* strname = strtok(s, "\"");
a->controller()->deleteObject(DtString(strname));
}
}
{
a->controller()->run();
}
{
DtStartResumeInteraction ds;
#if WIN32
s[strlen(s)]='\0';
#else
s[strlen(s)-1]='\0';
#endif
//if no arguments, send it to all backends
if (strcmp(s, "") == 0)
{
ds.setReceiverId(DtEntityIdentifier(DtSimSendToAll,0));
}
else
{
//get the backend id
if (strchr(s, ':'))
{
ds.setReceiverId(DtEntityIdentifier(DtSimulationAddress(s),0));
}
else
{
DtWarn << "Start who? (use site:host)";
return;
}
}
ds.setSenderId(DtEntityIdentifier(a->controller()->simulationAddress(),0));
a->controller()->vrfMessageInterface()->exerciseConn()->sendStamped(ds);
}
{
a->controller()->pause();
}
{
DtStopFreezeInteraction ds;
#if WIN32
s[strlen(s)]='\0';
#else
s[strlen(s)-1]='\0';
#endif
//if no arguments, send it to all backends
if (strcmp(s, "") == 0)
{
ds.setReceiverId(DtEntityIdentifier(DtSimSendToAll,0));
}
else
{
//get the backend id site:host
if (strchr(s, ':'))
{
ds.setReceiverId(DtEntityIdentifier(DtSimulationAddress(s),0));
}
else
{
DtWarn << "Stop who? (use site:host)";
return;
}
}
ds.setSenderId(DtEntityIdentifier(a->controller()->simulationAddress(),0));
a->controller()->vrfMessageInterface()->exerciseConn()->sendStamped(ds);
}
#ifdef _PowerUX
int strcasecmp(const char *s1, const char *s2)
{
char *s1Temp = strdup(s1);
char *s2Temp = strdup(s2);
for (int strIndex= 0; strIndex< strlen(s1Temp); strIndex++)
if ((64 < s1Temp[strIndex]) && (s1Temp[strIndex] < 91))
s1Temp[strIndex] += 32;
for (int strIndex= 0; strIndex< strlen(s2Temp); strIndex++)
if ((64 < s2Temp[strIndex]) && (s2Temp[strIndex] < 91))
s2Temp[strIndex] += 32;
int retVal = (strcmp(s1Temp,s2Temp));
free (s1Temp);
free (s2Temp);
return retVal;
}
#endif
#if WIN32
static char nbdf_buff[128];
static int nbdf_ptr=0;
char *non_blocking_dos_fgets(char *buff, int size, FILE *f)
{
while (_kbhit())
{
nbdf_buff[nbdf_ptr] = _getche();
if ( nbdf_buff[nbdf_ptr] == '\r'
|| nbdf_buff[nbdf_ptr] == '\n'
|| nbdf_ptr >= size )
{
nbdf_buff[nbdf_ptr] = 0; //terminate string
strcpy(buff,nbdf_buff);
nbdf_ptr=0;
DtInfo("\n");
return(buff);
}
else if ( nbdf_buff[nbdf_ptr] == '\b')
{
//Write out a blank space to erase whatever was there
_putch(' ');
//Move back before the space
_putch('\b');
--nbdf_ptr;
}
else
{
++nbdf_ptr;
}
}
return NULL;
}
#endif
#define LASTCHAR(s) (s[strlen(s)-1])
#define STERMINATE(s) do{ char *t=(s); if (*t) (s)++, *t='\0';} while(0)
/* returns pointer to next token separated by a sep character
* it's similar to strtok, but does not use internal static memory,
* and leaves nextp pointing to end of word
* note that gettok modifies the contents of the
* strings passed to it by replacing separators with '\0' */
char *gettok(char **nextp, char *sep)
{
char *start, *end;
start = *nextp;
while (*start && strchr(sep, *start))
start++;
if (!*start)
return NULL;
end = start;
while (*end && !strchr(sep, *end) )
end++;
*nextp = end;
STERMINATE(*nextp);
return start;
}
#if !WIN32
void setBlock(int fd, int on)
{
static int blockf, nonblockf;
static int first = 1;
if (first) {
first = 0;
int flags = fcntl(fd, F_GETFL, 0);
if (flags == -1)
DtWarnPerror("fcntl(F_GETFL) failed");
/* could use FNDELAY instead of FNONBLK, but then feof()
will be confused */
blockf = flags & ~O_NONBLOCK;
nonblockf = flags | O_NONBLOCK;
}
if (fcntl(0, F_SETFL, on ? blockf : nonblockf) < 0)
DtWarnPerror("fcntl(F_SETFL) failed");
}
#endif
Cmd *lookupCmd(char *cmdname)
{
if (!cmdname)
return NULL;
for (int j=0; j<nCmds; j++)
#if !WIN32
if (!strcasecmp(cmdname, allCmds[j].name))
#else
if (!_stricmp(cmdname, allCmds[j].name))
#endif
return allCmds+j;
return NULL;
}
DtVrfRemoteController* controller) :
kbInterest(0), myTimeToQuit(0),
myController(controller)
{
DtInfo("Scenario directory: %s\n", scenariosDir);
DtInfo("Terrain directory: %s\n", terrainDir);
myController->addBackendDiscoveryCallback(backendAddedCb, NULL);
myController->addBackendRemovalCallback(backendRemovedCb, NULL);
myController->addBackendLoadedCallback(backendLoadedCb, NULL);
myController->addScenarioLoadedCallback(ScenarioLoadedCb, NULL);
myController->addBackendSavedCallback(backendSavedCb, NULL);
myController->addScenarioSavedCallback(ScenarioSavedCb, NULL);
kbInterest++;
prompt();
}
{
}
{
myTimeToQuit = yesNo;
}
{
return myTimeToQuit;
}
{
return myController;
}
{
char buff[256];
int discardNext = 0;
UNBLOCK();
#if !WIN32
while (fgets(buff, sizeof(buff), stdin)) {
#else
while (non_blocking_dos_fgets(buff, sizeof(buff), stdin)) {
#endif
int discardThis = discardNext;
discardNext = (LASTCHAR(buff) != 10);
if (!discardThis) {
/* RESTORE/UNBLOCK are not necessary if you know you
won't terminate from within processCmd */
RESTORE();
processCmd(buff);
if (!kbInterest)
return;
UNBLOCK();
}
}
RESTORE();
if (feof(stdin)) {
DtInfo("EOF\n");
exit(0);
}
}
{
DtInfo("> ");
fflush(stdout);
}
{
char *cmdname = gettok(&buff, "\t \n");
Cmd *cmd = lookupCmd(cmdname);
if (cmd)
(*cmd->func)(buff, this);
else if (cmdname)
DtWarn("VRF Remote controller: no such command: \"%s\"\n", cmdname);
prompt();
}
void DtTextInterface::backendAddedCb(const DtSimulationAddress& addr, void* usr)
{
DtInfo("\nBackend %s Added\n> ", addr.string());
}
void DtTextInterface::backendRemovedCb(const DtSimulationAddress& addr, void* usr)
{
DtInfo("\nBackend %s Removed\n> ", addr.string());
}
void DtTextInterface::backendLoadedCb(const DtSimulationAddress& addr, void* usr)
{
DtInfo("\nBackend %s Loaded\n> ", addr.string());
}
{
DtInfo("\nScenario Loaded\n> ");
}
void DtTextInterface::backendSavedCb(const DtSimulationAddress& addr, DtSaveResult result, void* usr)
{
DtInfo("\nBackend %s Saved (%s)\n> ",
addr.string(), result == DtSuccess? "success" : "failure");
}
{
DtInfo("\nScenario Saved\n> ");
}
const DtString& name, const DtEntityIdentifier& id, void* usr)
{
static DtEntityIdentifier aggId;
//We want to check for the creation of the aggregate entity and keep a hold of it's entity id so that
//when it's subordinates are created we can add them to the aggregate's organization
DtString search = name;
if( search.findString("Tank_Plt") >=0 )
{
DtInfo("\n aggregate has been created with name and id: \"%s\", %s\n> ",
name.string(), id.string());
aggId = id;
}
else
{
DtInfo("\n entity has been created with name and id: \"%s\", %s\n> ",
name.string(), id.string());
}
//If the name of our new entity is one of our desired subordinates we will add it to the tank platoon
DtString sub = name;
if ( sub.findString("Plt_Sub") >= 0 )
{
//We grab hold of the remote controller and add our individual to the aggregate
DtVrfRemoteController* pVrfRemoteCtrl = (DtVrfRemoteController*)(usr);
//This entity belongs to our aggregate, add it to the platoon
if ( pVrfRemoteCtrl )
{
pVrfRemoteCtrl->addToOrganization(id, aggId);
DtInfo("\n %s has been added to aggregate with id: %s\n> ",name.string(),aggId.string());
}
}
}
{
//Let's parse the command string and then call
//the corresponding method on DtVrfRemoteController.
char *point, *name;
name = strtok(str, " ");
name = strtok(NULL, "\"");
point = strtok(NULL, " ");
if (!point || !name)
{
DtInfo("\tusage: create waypoint <\"name\"> <pt>\n");
return;
}
DtVector vec;
sscanf(point, "%lf,%lf,%lf", &vec[0], &vec[1], &vec[2]);
controller()->createWaypoint(vrfObjectCreatedCb, (void*)"waypoint", vec,
name);
}
{
//Let's parse the command string and then call
//the corresponding method on DtVrfRemoteController.
char *name, *point;
name = strtok(str, " ");
name = strtok(NULL, "\"");
if (!name)
{
DtInfo("\tusage: create route <\"name\"> <p1 p2 ... pn>\n");
return;
}
//create list of vertices
DtList vertices;
while ((point = strtok(NULL, " ")) != NULL)
{
double x, y, z;
sscanf(point, "%lf,%lf,%lf", &x, &y, &z);
DtVector* vec = new DtVector(x, y, z);
vertices.add(vec);
}
controller()->createRoute(vrfObjectCreatedCb, (void*)"route", vertices,
name);
//empty list of vertices
DtListItem* next = NULL;
for (DtListItem* item = vertices.first(); item; item = next)
{
next = item->next();
delete (DtVector*) vertices.remove(item);
}
}
{
//Let's parse the command string and then call
//the corresponding method on DtVrfRemoteController.
char *point;
point = strtok(&str[4], " ");
if (!point)
{
DtInfo("\tusage: tank <geocentric_location>\n");
return;
}
DtVector vec;
sscanf(point, "%lf,%lf,%lf", &vec[0], &vec[1], &vec[2]);
vrfObjectCreatedCb, (void*)"tank",
DtEntityType(1, 1, 225, 1, 1, 3, 0), vec,
DtForceFriendly, 90.0);
}
{
//Let's parse the command string and then call
//the corresponding method on DtVrfRemoteController.
char *name, *route;
name = strtok(str, " ");
name = strtok(NULL, "\"");
route = strtok(NULL, "\""); //get past whitespace
route = strtok(NULL, "\"");
if (!name || !route)
{
DtInfo("\tusage: task patrolRoute <\"name\"> <\"route\">\n");
return;
}
controller()->patrolAlongRoute(name, route);
}
{
//Let's parse the command string and then call
//the corresponding method on DtVrfRemoteController.
char *name, *point;
name = strtok(str, " ");
name = strtok(NULL, "\"");
point = strtok(NULL, "\""); //get past whitespace
point = strtok(NULL, "\"");
if (!name || !point)
{
DtInfo("\tusage: task moveToPoint <\"name\"> <\"waypoint\">\n");
return;
}
controller()->moveToWaypoint(name, point);
}
void DtTextInterface::follow(char* str)
{
//Let's parse the command string and then call
//the corresponding method on DtVrfRemoteController.
char *name, *leader;
name = strtok(str, " ");
name = strtok(NULL, "\"");
leader = strtok(NULL, "\""); //get past white space
leader = strtok(NULL, "\"");
if (!name || !leader)
{
DtInfo("\tusage: task follow <name> <leader>\n");
return;
}
DtVector offset(10.0, 0.0, 0.0);
controller()->followEntity(name, leader, offset);
}
void DtTextInterface::wait(char* str)
{
//Let's parse the command string and then call
//the corresponding method on DtVrfRemoteController.
char *name, *t;
name = strtok(str, " ");
name = strtok(NULL, "\"");
t = strtok(NULL, " ");
if (!name || !t)
{
DtInfo("\tusage: task wait <\"name\"> <time>\n");
return;
}
DtTime time = atof(t);
controller()->waitDuration(name, time);
}
void DtTextInterface::setPlan(char* str)
{
//Let's parse the command string and then call
//the corresponding method on DtVrfRemoteController.
char *name = strtok(str, " ");
name = strtok(NULL, "\"");
if (!name)
{
DtInfo("\tusage: set plan <\"entity name\">\n");
return;
}
//Create a plan
//This plan will contain four statements:
//1. Set heading to 2.094395 radians
//2. Set speed to 5 m/s
//3. Wait 20 seconds
//4. Move to waypoint "alpha"
DtPlan plan;
plan.init();
waitTask.setSecondsToWait(20.0);
DtMoveToTask moveTask;
moveTask.setControlPtName("alpha");
DtSetHeadingRequest headingReq;
headingReq.setHeading(2.094395);
speedReq.setSpeed(5);
DtSetDataRequestStmt stmt1, stmt2;
DtTaskStmt stmt3, stmt4;
stmt1.setSetDataRequest(&headingReq);
stmt2.setSetDataRequest(&speedReq);
stmt3.setTask(&waitTask);
stmt4.setTask(&moveTask);
//Create a conditional expression.
//This is just a simple example of a condition that will always be
//true when the entity is first created -- it checks to see if the fuel
//is non-zero.
DtCeResourceOperator conditionalExpression;
conditionalExpression.setResource("fuel");
conditionalExpression.setOper(">");
conditionalExpression.setComparisonValue(0.0);
//Create an if statement using the conditional expression
DtIfStmt ifStatement;
ifStatement.setCondExpr(&conditionalExpression);
ifStatement.thenBlock()->add(stmt1.clone());
ifStatement.thenBlock()->addToEnd(stmt2.clone());
ifStatement.thenBlock()->addToEnd(stmt3.clone());
ifStatement.thenBlock()->addToEnd(stmt4.clone());
DtPlanBlock* block = plan.mainBlock();
block->addToStart(ifStatement.clone());
//Assign the plan to the given entitiy
controller()->assignPlanByName(name, plan);
//Let's subscribe to the given entity's plan messages.
//This will let us know whether or "assignPlan" command
//was successfull. Also, it will also notify us if any
//changes were made to the plan.
controller()->subscribePlan(name, planCb, NULL);
//Let's register a callback for current statement
//messages. Our callback will be invoked whenever the entity
//starts a new statement in the plan.
//Let's also register a callback for when the entity completes
//the plan. Inside our callback, we unsubscribe to this entity's
//plan messages and unregister our current statement callback.
}
const DtList& stmts, bool append, void* usr)
{
//Let's print the statements in the plan.
//Because plans can be large, their statements may arrive in separate plan
//messages. The append flag let's us know whether these statements belong to
//a plan we already have.
if (append)
{
DtInfo("\nAdditional plan statements for %s.\n", name.string());
}
else
{
DtInfo("\nNew plan statements for %s.\n", name.string());
}
int i = 0;
for (DtListItem* item = stmts.first(); item; item = item->next())
{
DtSimStatement* statement = (DtSimStatement*) item->data();
DtInfo("\t%d) %s\n", ++i, statement->stringRep().string());
}
DtInfo("\n> ");
}
void* usr)
{
//Let's print the statement that 'id' is executing. A statementId = 0
//indicates that the 'id' hasn't started its plan yet.
if (status.currentStatementId > 0)
{
DtInfo("\n%s executing statement %d\n> ", id.string(),
}
}
void DtTextInterface::planCompleteCb(const DtString& id, void* usr)
{
//Let's print that 'id' has completed the plan.
DtInfo("\n%s has completed its plan!\n> ", id.string());
//Because the plan we assigned is now complete, we no longer need the
//plan callbacks we registered. Let's unregister them here.
controller->unsubscribePlan(id, planCb, NULL);
controller->removePlanStatementCallback(id, planStmtCb, NULL);
}
{
//Let's parse the command string and then call
//the corresponding method on DtVrfRemoteController.
char *objId, *label;
objId = strtok(str, " ");
objId = strtok(NULL, " ");
label = strtok(NULL, "\"");
if (!objId || !label)
{
DtInfo("\tusage: set label <object id> <\"label\">\n");
return;
}
controller()->setLabel(objId, label);
}
{
//Let's parse the command string and then call
//the corresponding method on DtVrfRemoteController.
char *name, *point;
name = strtok(str, " ");
name = strtok(NULL, "\"");
point = strtok(NULL, " ");
if (!name || !point)
{
DtInfo("\tusage: set location <\"name\"> <pt>\n");
return;
}
DtVector vec;
sscanf(point, "%lf,%lf,%lf", &vec[0], &vec[1], &vec[2]);
controller()->setLocation(name, vec);
}
void DtTextInterface::setFuel(char* str)
{
//Let's parse the command string and then call
//the corresponding method on DtVrfRemoteController.
char *name, *amount;
name = strtok(str, " ");
name = strtok(NULL, "\"");
amount = strtok(NULL, " ");
if (!name || !amount)
{
DtInfo("\tusage: set fuel <\"name\"> <double>\n");
return;
}
double fa = atof(amount);
controller()->setResource(name, "fuel", fa);
}
{
//Let's parse the command string and then call
//the corresponding method on DtVrfRemoteController.
char *name, *target;
name = strtok(str, " ");
name = strtok(NULL, "\"");
target = strtok(NULL, "\""); //get past whitespace
target = strtok(NULL, "\"");
if (!name || !target)
{
DtInfo("\tusage: set target <\"name\"> <\"name\">\n");
return ;
}
controller()->setTarget(name, target);
}
{
//Let's parse the command string and then call
//the corresponding method on DtVrfRemoteController.
char *name;
name = strtok(str, " ");
name = strtok(NULL, "\"");
if (!name)
{
DtInfo("\tusage: set restore <\"name\"> \n");
return;
}
controller()->restore(name);
}

Document ID: Generated on Mon Apr 8 19:24:01 EDT 2013 from SVN revision 125877
Copyright © 2005-2013 VT MÄK. All Rights Reserved (www.mak.com)