VR-Vantage 2.5 API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
exampleGimbalPlugin

DtGimbalDriver looks for the plane element created by DtExampleDriver (or DtDriverExamplePlugin) and implements a gimbal attached to that plane at a specified offset.

It shows how to use the DtGeoReference class to position and orient the gimbal using the plane's position and orientation; and how to find azimuth and elevation angles to a target in the gimbal's local coordinate system. It attaches the observer named "Observer 1" to the gimbal, and uses the azimuth and elevation angles determined to lock the observer onto the target location.

Example Source Files

DtGimbalDriver.h

/*****************************************************************************
* Copyright (c) 2017 MAK Technologies, Inc.
* All rights reserved.
*****************************************************************************/
#pragma once
#include <string>
namespace makVrv
{
class DtGeoReference;
class DtSceneObjectAgent;
class DtSceneObject;
}
class DtGeodeticCoord;
{
public:
virtual ~DtGimbalDriver();
virtual const std::string& className() const;
protected:
virtual bool onStart();
virtual bool onStop();
virtual bool onTick();
virtual void attachObserverToEntity( const std::string& entityName );
virtual void slot_displayEngineAdded( const makVrv::DtDeRecord& igRecord );
virtual bool initialize();
private:
protected:
DtGeodeticCoord* myTargetLocation;
};

DtGimbalDriver.cxx

/*****************************************************************************
* Copyright (c) 2017 MAK Technologies, Inc.
* All rights reserved.
*****************************************************************************/
#include "DtGimbalDriver.h"
#include <vrvCore/DtDe.h>
#include <vlutil/vlUtil.h>
// Use the VR-Vantage namespace.
// All classes in VR-Vantage are in this namespace.
using namespace makVrv;
const double DtTargetLatitude = DtDeg2Rad(10.0327245110);
const double DtTargetLongitude = DtDeg2Rad(60.0271819335);
const double DtTargetAltitude = 29.389;
const double DtGimbalForwardOffset = 2.0;
const double DtGimbalDownOffset = 2.5;
const double DtGimbalRightOffset = 0.;
: makVrv::DtDriver( am, "DtGimbalDriver" )
, myPlaneGeoRef( 0 )
, myGimbalGeoRef( 0 )
, myGimbalSceneObjectAgent( 0 )
, myTargetLocation( 0 )
{
myTargetLocation = new DtGeodeticCoord( DtTargetLatitude, DtTargetLongitude, DtTargetAltitude,
myAgentManager.de().sharedState().coordinateSystem().referenceEllipsoid() );
mySignalConnections += DtDeSharedStateSignaler::instance( myAgentManager.de() )
.signal_coordinateSystemChanged.connect( boost::bind(
}
{
{
}
DtDELETE( myPlaneGeoRef );
DtDELETE( myGimbalGeoRef );
DtDELETE( myTargetLocation );
}
{
DtDELETE( myTargetLocation );
myTargetLocation = new DtGeodeticCoord( DtTargetLatitude, DtTargetLongitude, DtTargetAltitude,
}
{
static std::string name = "DtGimbalDriver";
return name;
}
{
// look up the plane from exampleDriver (or exampleDriverPlugin)
// It has display name "Entity From Facade"
bool found = false;
// Iterate through all the elements
DtElementData::ElementEntryMap::const_iterator curIter =
elemData.elements().begin();
DtElementData::ElementEntryMap::const_iterator endIter =
elemData.elements().end();
for( ; curIter != endIter; ++curIter )
{
DtElementEntry* entry = curIter->second;
dynamic_cast<const DtElementAttributeDisplayName*>(
entry->findAttribute(DtElementAttributes::DisplayName));
if ( name && name->value() == "Entity From Facade" )
{
// Found it. Look up the scene object id used to visualize this element
// in the 3D model set. We can use that scene object to get the position
// and orientation of the plane
DtElementID planeElementId = entry->elementID();
elemData.getSceneObjectIds(planeElementId,
sceneObjectIds, DtSceneObject::ModelSet_3D );
// getSceneObjectIds() can return multiple scene object ids if multiple model sets
// are specified. Since we only asked for the 3D model set scene object,
// sceneObjectIds.size() should be 1.
if ( sceneObjectIds.size() == 1 )
{
DtAgentUpdateResolverInterface* updater = agentManager().findUpdater( sceneObjectIds.front() );
if(updater)
{
found = true;
}
}
}
}
// If we didn't find it, assume it hasn't been created yet. Return false, and we'll
// try again next tick
if (! found )
{
return false;
}
// We have the plane's scene object. Now we can create GeoReferences for the
// plane and the Gimbal
// We create a scene object (and associate it with an element) for the Gimbal so that
// our observer can be attached to it. When an observer is attached to an element in
// Mimic mode, it effectively uses that element's coordinate system; so attaching to
// this Gimbal gives us an observer in Gimbal coordinates. Note that no models are
// added to the scene object, so this element will be invisible (but if you had a 3D
// gimbal model you could create and add it here
myGimbalSceneObjectAgent = DtSceneObjectAgent::create( myAgentManager );
myGimbalSceneObjectAgent->setModelSet( 0 );
// Set up the element
myGimbalSceneObjectAgent->setElementID( myGimbalId );
reportElementCreated( myGimbalId, 0, DtElementEntry::Entity );
// Give the element a name that we can use to attach to it
return true;
}
{
return true;
}
{
return true;
}
{
if ( myGimbalSceneObjectAgent == NULL )
{
if ( ! initialize() )
{
return true;
}
// The plane was found. Attach to it.
}
// Set up a GeoRef for the plane. We use this to find the Gimbal position
// and orientation for the Gimbal scene object (and Gimbal GeoRef)
DtVector planePosition;
DtTaitBryan planeOrientation;
myPlaneSceneObject->getPosition( 0, planePosition );
myAgentManager.de().sharedState().coordinateSystem() ), planeOrientation );
// Find the position and orientation of the gimbal in geodetic coordinates, using
// the GeoRef placed above;
DtGeodeticCoord gimbalGeod;
DtTaitBryan gimbalOri;
DtVector( DtGimbalForwardOffset, DtGimbalRightOffset, DtGimbalDownOffset),
DtTaitBryan(0., 0., 0.),
gimbalGeod, gimbalOri );
// Set up a GeoRef for our Gimbal
myGimbalGeoRef->setLocationAndOrientation( gimbalGeod, gimbalOri );
// Position our gimbal object
myGimbalSceneObjectAgent->setPosition( 0, DtGeodeticToLocal( gimbalGeod,
myGimbalSceneObjectAgent->setTopographicOrientation( 0, gimbalOri );
// Get tower location in gimbal's topocentric system. (We don't need the tower's orientation)
DtVector targetTopo;
DtTaitBryan unused( 0., 0., 0. );
myGimbalGeoRef->geodeticToTopo( *myTargetLocation, unused, targetTopo, unused );
// find azimuth and elevation angles to our target
double azimuthAngle = -atan2( targetTopo[1], targetTopo[0] );
double xyPlaneDistance = sqrt( targetTopo[0] * targetTopo[0] + targetTopo[1] * targetTopo[1] );
double elevationAngle = DtDeg2Rad( 90. ) - atan2( xyPlaneDistance, -targetTopo[2] );
// Get the main observer
if ( observer )
{
// Set the observer's azimuth and elevation angle to keep the tower in view
observer->setAttachedOrientation( azimuthAngle, elevationAngle, 0. );
}
return true;
}
{
DtObserver* observer = myAgentManager.de().
driverManager().inputDriver().findObserverByName( "Observer 1" );
if ( observer )
{
// Start by getting the existing observer state record for this observer.
// We can modify it and then set it back. We use the observer record
// mechanism because it will allow the observer to attach even if the
// plane hasn't been created yet (the observer will retry attaching when
// an observer record is used until the attach succeeds
observer->getRecord( observerState );
// Attach to the plane
std::set<std::string> displayNames;
displayNames.insert( entityName );
observerState.setAttachedToDisplayNames( displayNames );
// We want no offset
observerState.setObserverOffsetVector( 0., 0., 0. );
// Get the observer settings record associated with this observer state record
// so we can force the attach type to mimic
// Add the modified settings record back to the observer state record
observerState.setObserverSettingsRecord( settingsRec );
// Set a view magnification
observerState.setViewMagnification( 100. );
// ... and then add the observer state to the observer
observer->setFromRecord( observerState );
}
}
{
stop();
start();
}


Copyright © 2005-2019 VT MAK. All Rights Reserved (www.mak.com)