1
0
Fork 0

Fix some sim time issues with the locations of the ground cache and the

queries in there.

Modified Files:
 	flight.cxx flight.hxx groundcache.cxx
	groundcache.hxx JSBSim/JSBSim.cxx YASim/YASim.cxx
	YASim/YASim.hxx
This commit is contained in:
frohlich 2009-03-15 11:26:31 +00:00 committed by Tim Moore
parent da8b3f9ce5
commit db2d4a7a68
7 changed files with 60 additions and 34 deletions

View file

@ -442,7 +442,8 @@ void FGJSBsim::update( double dt )
cart = FGLocation(lon, lat, alt+slr); cart = FGLocation(lon, lat, alt+slr);
} }
double cart_pos[3] = { cart(1), cart(2), cart(3) }; double cart_pos[3] = { cart(1), cart(2), cart(3) };
bool cache_ok = prepare_ground_cache_ft( State->Getsim_time(), cart_pos, double t0 = State->Getsim_time();
bool cache_ok = prepare_ground_cache_ft( t0, t0 + dt, cart_pos,
groundCacheRadius ); groundCacheRadius );
if (!cache_ok) { if (!cache_ok) {
SG_LOG(SG_FLIGHT, SG_WARN, SG_LOG(SG_FLIGHT, SG_WARN,

View file

@ -43,7 +43,8 @@ static const float W2HP = 1.3416e-3;
static const float INHG2PA = 3386.389; static const float INHG2PA = 3386.389;
static const float SLUG2KG = 14.59390; static const float SLUG2KG = 14.59390;
YASim::YASim(double dt) YASim::YASim(double dt) :
_simTime(0)
{ {
// set_delta_t(dt); // set_delta_t(dt);
_fdm = new FGFDM(); _fdm = new FGFDM();
@ -209,7 +210,7 @@ void YASim::update(double dt)
// build the environment cache. // build the environment cache.
float vr = _fdm->getVehicleRadius(); float vr = _fdm->getVehicleRadius();
vr += 2.0*FT2M*dt*Math::mag3(v); vr += 2.0*FT2M*dt*Math::mag3(v);
prepare_ground_cache_m( 0.0, xyz, vr ); prepare_ground_cache_m( _simTime, _simTime + dt, xyz, vr );
// Track time increments. // Track time increments.
FGGround* gr FGGround* gr
@ -217,14 +218,15 @@ void YASim::update(double dt)
int i; int i;
for(i=0; i<iterations; i++) { for(i=0; i<iterations; i++) {
gr->setTimeOffset(i*_dt); gr->setTimeOffset(_simTime + i*_dt);
copyToYASim(false); copyToYASim(false);
_fdm->iterate(_dt); _fdm->iterate(_dt);
copyFromYASim(); copyFromYASim();
} }
// Reset the time increment. // Increment the local sim time
gr->setTimeOffset(0.0); _simTime += dt;
gr->setTimeOffset(_simTime);
} }
void YASim::copyToYASim(bool copyState) void YASim::copyToYASim(bool copyState)

View file

@ -25,6 +25,7 @@ public:
yasim::FGFDM* _fdm; yasim::FGFDM* _fdm;
float _dt; float _dt;
double _simTime;
enum { enum {
NED, NED,
UVW, UVW,

View file

@ -643,18 +643,21 @@ void FGInterface::_busdump(void) {
} }
bool bool
FGInterface::prepare_ground_cache_m(double ref_time, const double pt[3], FGInterface::prepare_ground_cache_m(double startSimTime, double endSimTime,
double rad) const double pt[3], double rad)
{ {
return ground_cache.prepare_ground_cache(ref_time, SGVec3d(pt), rad); return ground_cache.prepare_ground_cache(startSimTime, endSimTime,
SGVec3d(pt), rad);
} }
bool FGInterface::prepare_ground_cache_ft(double ref_time, const double pt[3], bool
double rad) FGInterface::prepare_ground_cache_ft(double startSimTime, double endSimTime,
const double pt[3], double rad)
{ {
// Convert units and do the real work. // Convert units and do the real work.
SGVec3d pt_ft = SG_FEET_TO_METER*SGVec3d(pt); SGVec3d pt_ft = SG_FEET_TO_METER*SGVec3d(pt);
return ground_cache.prepare_ground_cache(ref_time, pt_ft, rad*SG_FEET_TO_METER); return ground_cache.prepare_ground_cache(startSimTime, endSimTime,
pt_ft, rad*SG_FEET_TO_METER);
} }
bool bool
@ -825,29 +828,34 @@ FGInterface::get_groundlevel_m(const SGGeod& geod)
double ref_time, radius; double ref_time, radius;
// Prepare the ground cache for that position. // Prepare the ground cache for that position.
if (!is_valid_m(&ref_time, cpos.data(), &radius)) { if (!is_valid_m(&ref_time, cpos.data(), &radius)) {
bool ok = prepare_ground_cache_m(ref_time, pos.data(), 10); double startTime = globals->get_sim_time_sec();
double endTime = startTime + 1;
bool ok = prepare_ground_cache_m(startTime, endTime, pos.data(), 10);
/// This is most likely the case when the given altitude is /// This is most likely the case when the given altitude is
/// too low, try with a new altitude of 10000m, that should be /// too low, try with a new altitude of 10000m, that should be
/// sufficient to find a ground level below everywhere on our planet /// sufficient to find a ground level below everywhere on our planet
if (!ok) { if (!ok) {
pos = SGVec3d::fromGeod(SGGeod::fromRadM(geod.getLongitudeRad(), geod.getLatitudeRad(), 10000)); pos = SGVec3d::fromGeod(SGGeod::fromGeodM(geod, 10000));
/// If there is still no ground, return sea level radius /// If there is still no ground, return sea level radius
if (!prepare_ground_cache_m(ref_time, pos.data(), 10)) if (!prepare_ground_cache_m(startTime, endTime, pos.data(), 10))
return 0; return 0;
} }
} else if (radius*radius <= distSqr(pos, cpos)) { } else if (radius*radius <= distSqr(pos, cpos)) {
double startTime = globals->get_sim_time_sec();
double endTime = startTime + 1;
/// We reuse the old radius value, but only if it is at least 10 Meters .. /// We reuse the old radius value, but only if it is at least 10 Meters ..
if (!(10 < radius)) // Well this strange compare is nan safe if (!(10 < radius)) // Well this strange compare is nan safe
radius = 10; radius = 10;
bool ok = prepare_ground_cache_m(ref_time, pos.data(), radius); bool ok = prepare_ground_cache_m(startTime, endTime, pos.data(), radius);
/// This is most likely the case when the given altitude is /// This is most likely the case when the given altitude is
/// too low, try with a new altitude of 10000m, that should be /// too low, try with a new altitude of 10000m, that should be
/// sufficient to find a ground level below everywhere on our planet /// sufficient to find a ground level below everywhere on our planet
if (!ok) { if (!ok) {
pos = SGVec3d::fromGeod(SGGeod::fromRadM(geod.getLongitudeRad(), geod.getLatitudeRad(), 10000)); pos = SGVec3d::fromGeod(SGGeod::fromGeodM(geod, 10000));
/// If there is still no ground, return sea level radius /// If there is still no ground, return sea level radius
if (!prepare_ground_cache_m(ref_time, pos.data(), radius)) if (!prepare_ground_cache_m(startTime, endTime, pos.data(), radius))
return 0; return 0;
} }
} }

View file

@ -603,10 +603,10 @@ public:
// Prepare the ground cache for the wgs84 position pt_*. // Prepare the ground cache for the wgs84 position pt_*.
// That is take all vertices in the ball with radius rad around the // That is take all vertices in the ball with radius rad around the
// position given by the pt_* and store them in a local scene graph. // position given by the pt_* and store them in a local scene graph.
bool prepare_ground_cache_m(double ref_time, const double pt[3], bool prepare_ground_cache_m(double startSimTime, double endSimTime,
double rad); const double pt[3], double rad);
bool prepare_ground_cache_ft(double ref_time, const double pt[3], bool prepare_ground_cache_ft(double startSimTime, double endSimTime,
double rad); const double pt[3], double rad);
// Returns true if the cache is valid. // Returns true if the cache is valid.

View file

@ -134,10 +134,24 @@ public:
const SGSceneUserData::Velocity* velocity = getVelocity(transform); const SGSceneUserData::Velocity* velocity = getVelocity(transform);
SGVec3d center = _center; SGVec3d center = _center;
_center = SGVec3d(inverseMatrix.preMult(_center.osg()));
double radius = _radius; double radius = _radius;
if (velocity) _center = SGVec3d(inverseMatrix.preMult(_center.osg()));
_radius += (_endTime - _startTime)*norm(velocity->linear); if (velocity) {
SGVec3d staticCenter(_center);
double dtStart = velocity->referenceTime - _startTime;
SGVec3d startCenter = staticCenter + dtStart*velocity->linear;
SGVec3d angle = dtStart*velocity->angular;
startCenter = SGQuatd::fromAngleAxis(angle).transform(startCenter);
double dtEnd = velocity->referenceTime - _endTime;
SGVec3d endCenter = staticCenter + dtEnd*velocity->linear;
angle = dtEnd*velocity->angular;
endCenter = SGQuatd::fromAngleAxis(angle).transform(endCenter);
_center = 0.5*(startCenter + endCenter);
_radius += 0.5*dist(startCenter, endCenter);
}
simgear::BVHSubTreeCollector::NodeList parentNodeList; simgear::BVHSubTreeCollector::NodeList parentNodeList;
mSubTreeCollector.pushNodeList(parentNodeList); mSubTreeCollector.pushNodeList(parentNodeList);
@ -152,7 +166,8 @@ public:
bvhTransform->setToWorldTransform(SGMatrixd(matrix.ptr())); bvhTransform->setToWorldTransform(SGMatrixd(matrix.ptr()));
bvhTransform->setLinearVelocity(velocity->linear); bvhTransform->setLinearVelocity(velocity->linear);
bvhTransform->setAngularVelocity(velocity->angular); bvhTransform->setAngularVelocity(velocity->angular);
bvhTransform->setReferenceTime(_startTime); bvhTransform->setReferenceTime(velocity->referenceTime);
bvhTransform->setStartTime(_startTime);
bvhTransform->setEndTime(_endTime); bvhTransform->setEndTime(_endTime);
bvhTransform->setId(velocity->id); bvhTransform->setId(velocity->id);
@ -236,8 +251,8 @@ FGGroundCache::~FGGroundCache()
} }
bool bool
FGGroundCache::prepare_ground_cache(double ref_time, const SGVec3d& pt, FGGroundCache::prepare_ground_cache(double startSimTime, double endSimTime,
double rad) const SGVec3d& pt, double rad)
{ {
// Empty cache. // Empty cache.
found_ground = false; found_ground = false;
@ -260,21 +275,20 @@ FGGroundCache::prepare_ground_cache(double ref_time, const SGVec3d& pt,
reference_wgs84_point = pt; reference_wgs84_point = pt;
reference_vehicle_radius = rad; reference_vehicle_radius = rad;
// Store the time reference used to compute movements of moving triangles. // Store the time reference used to compute movements of moving triangles.
cache_ref_time = ref_time; cache_ref_time = startSimTime;
// Get a normalized down vector valid for the whole cache // Get a normalized down vector valid for the whole cache
SGQuatd hlToEc = SGQuatd::fromLonLat(geodPt); SGQuatd hlToEc = SGQuatd::fromLonLat(geodPt);
down = hlToEc.rotate(SGVec3d(0, 0, 1)); down = hlToEc.rotate(SGVec3d(0, 0, 1));
// Get the ground cache, that is a local collision tree of the environment // Get the ground cache, that is a local collision tree of the environment
double endTime = cache_ref_time + 1; //FIXME?? CacheFill subtreeCollector(pt, rad, startSimTime, endSimTime);
CacheFill subtreeCollector(pt, rad, cache_ref_time, endTime);
globals->get_scenery()->get_scene_graph()->accept(subtreeCollector); globals->get_scenery()->get_scene_graph()->accept(subtreeCollector);
_localBvhTree = subtreeCollector.getBVHNode(); _localBvhTree = subtreeCollector.getBVHNode();
// Try to get a croase altitude value for the ground cache // Try to get a croase altitude value for the ground cache
SGLineSegmentd line(pt, pt + 2*reference_vehicle_radius*down); SGLineSegmentd line(pt, pt + 2*reference_vehicle_radius*down);
simgear::BVHLineSegmentVisitor lineSegmentVisitor(line, ref_time); simgear::BVHLineSegmentVisitor lineSegmentVisitor(line, startSimTime);
if (_localBvhTree) if (_localBvhTree)
_localBvhTree->accept(lineSegmentVisitor); _localBvhTree->accept(lineSegmentVisitor);

View file

@ -50,8 +50,8 @@ public:
// Prepare the ground cache for the wgs84 position pt_*. // Prepare the ground cache for the wgs84 position pt_*.
// That is take all vertices in the ball with radius rad around the // That is take all vertices in the ball with radius rad around the
// position given by the pt_* and store them in a local scene graph. // position given by the pt_* and store them in a local scene graph.
bool prepare_ground_cache(double ref_time, const SGVec3d& pt, bool prepare_ground_cache(double startSimTime, double endSimTime,
double rad); const SGVec3d& pt, double rad);
// Returns true if the cache is valid. // Returns true if the cache is valid.
// Also the reference time, point and radius values where the cache // Also the reference time, point and radius values where the cache