Upon running this example, an F-18 will appear in an orbit over Makland. A box is drawn to indicate the F-18's starting position, and a cylinder connects the F-18 to the box. A sphere is also drawn, bouncing between the F-18 and the box along the cylinder. When the example is running, you can press 'h' (and press enter) to hide the drawn objects (box/cylinder/sphere). Pressing 's' will show them again. Typing 'q' will shut down the example.
This example is an application. You can run it by running ./bin/exampleSendDrawControl<protocol>.exe (on Windows) or ./bin/exampleSendDrawControl<protocol> (on Linux). For more information about running examples, please see Running Applications and Examples.
#include <vl/exerciseConn.h>
#include <vl/exerciseConnInitializer.h>
#include <matrix/geodeticCoord.h>
#include <vlutil/vlKeyboard.h>
#include <vl/entityPublisher.h>
#include <vl/entityStateRepository.h>
#include <vl/topoView.h>
#include <vl/dataInteraction.h>
using namespace vrvControlToolkit;
DtVector position;
DtVector velocity;
DtVector acceleration;
DtTaitBryan euler;
DtVector rotationRate;
double scalerAcceleration = 0.0;
double speed = 0.0;
double turnRate = 0.0;
DtTime dt = 0.05;
int keyTick()
{
char *keyPtr = DtPollBlockingInputLine();
if (keyPtr && (*keyPtr == 'q' || *keyPtr == 'Q'))
{
return -1;
}
if (keyPtr && (*keyPtr == 's' || *keyPtr == 'S'))
{
return 1;
}
if (keyPtr && (*keyPtr == 'h' || *keyPtr == 'H'))
{
return 2;
}
return 0;
}
void initSpatial()
{
position.setZ(-1230);
speed = 40.0;
double turnRadius = -250.0;
turnRate = speed / turnRadius;
double roll = atan(5.0 * turnRate);
euler.setPsi(DtDeg2Rad(180));
euler.setPhi(roll);
double psi = euler.psi();
double cosPsi = cos( psi );
double sinPsi = sin( psi );
double phi = euler.phi();
double cosPhi = cos( phi );
double sinPhi = sin( phi );
velocity.setX(cosPsi * speed);
velocity.setY(sinPsi * speed);
velocity.setZ(0.0);
scalerAcceleration = speed * turnRate;
acceleration.setX(-scalerAcceleration * sinPsi);
acceleration.setY(scalerAcceleration * cosPsi);
acceleration.setZ(0.0);
rotationRate.setX(0.0);
rotationRate.setY(sinPhi * turnRate);
rotationRate.setZ(cosPhi * turnRate);
}
void updateSpatial()
{
double psi =
DtModPerZero( ( euler.psi() + ( turnRate * dt ) ), M_2PI );
euler.setPsi( psi );
for( int i=0; i<3; ++i )
{
position[i] += ( velocity[i] + 0.5 * acceleration[i] * dt ) * dt;
velocity[i] += acceleration[i] * dt;
}
acceleration[0] = -scalerAcceleration * sin( psi );
acceleration[1] = scalerAcceleration * cos( psi );
acceleration[2] = 0.0;
}
int main(int argc, char** argv)
{
appInit.parseCmdLine();
DtExerciseConn exConn(appInit);
exConn.setApplicationId(3, 5);
DtEntityType entType(1, 2, 225, 1, 9, 0, 0);
DtEntityPublisher f18(entType, &exConn, DtDrDrmRvw, DtForceFriendly,
DtEntityPublisher::guiseSameAsType());
DtTopoView topoView(f18.esr(), DtDeg2Rad(10.0), DtDeg2Rad(60.0));
initSpatial();
f18.esr()->setMarkingText("VR-Link F18");
int startId = 12;
DtGeodeticCoord
coord(DtDeg2Rad(10), DtDeg2Rad(60), 1230);
DtVector geocentricCoord;
coord.getGeocentric(geocentricCoord);
geocentricCoord, 25, 25, 25);
double spherePosition = 0;
10, 10, 10));
"Sphere");
sphereTemplate.createAttributeTemplate("Position", 0.0, 100.0);
spherePlacard.setRemoteGraphicSet("3D Graphics::Placards");
"Entity");
&entityTemplate, f18.globalId());
entityPlacard.setNumericAttributeValue("Speed", speed);
entityPlacard.setRemoteGraphicSet("3D Graphics::Placards");
DtClock* clock = exConn.clock();
DtTime simTime = 0;
bool sphereIncreasing = true;
while (true)
{
int key = keyTick();
if (key == -1)
{
break;
}
else if (key == 1)
{
DtDataInteraction dataInter;
marshaller.
encode(&rgCommand, &dataInter);
exConn.sendStamped(dataInter);
}
else if (key == 2)
{
DtDataInteraction dataInter;
marshaller.
encode(&rgCommand, &dataInter);
exConn.sendStamped(dataInter);
}
clock->setSimTime(simTime);
exConn.drainInput();
updateSpatial();
topoView.setLocation(position);
topoView.setVelocity(DtVector64To32(velocity));
topoView.setAcceleration(DtVector64To32(acceleration));
topoView.setOrientation(euler);
topoView.setRotationalVelocity(DtVector64To32(rotationRate));
if (sphereIncreasing)
{
spherePosition += 1.0;
if (spherePosition >= 100.0)
{
sphereIncreasing = false;
}
}
else
{
spherePosition -= 1.0;
if (spherePosition <= 0)
{
sphereIncreasing = true;
}
}
spherePlacard.setValueBarAttributeValue("Position", spherePosition);
entityPlacard.setNumericAttributeValue("Heading", (int)DtRad2Deg(topoView.orientation().psi()));
entityPlacard.setNumericAttributeValue("Speed", speed);
f18.tick();
sphereTemplate.update();
spherePlacard.update();
entityTemplate.update();
entityPlacard.update();
DtTime sleeptime = ( simTime += dt ) - clock->elapsedRealTime();
DtSleep( sleeptime );
}
return 0;
}