Use ground-network to improve MP start location.
Search for the closest ground-net node near but /not/ on, the requested runway. This works fairly well, although for some airports the selected node is surprisingly far from the runway.
This commit is contained in:
parent
1c4656512a
commit
eaf779deb2
3 changed files with 39 additions and 18 deletions
src
|
@ -36,6 +36,9 @@
|
||||||
#include <simgear/scene/util/OsgMath.hxx>
|
#include <simgear/scene/util/OsgMath.hxx>
|
||||||
#include <simgear/structure/exception.hxx>
|
#include <simgear/structure/exception.hxx>
|
||||||
#include <simgear/timing/timestamp.hxx>
|
#include <simgear/timing/timestamp.hxx>
|
||||||
|
#include <simgear/math/SGLineSegment.hxx>
|
||||||
|
#include <simgear/math/SGGeometryFwd.hxx>
|
||||||
|
#include <simgear/math/SGIntersect.hxx>
|
||||||
|
|
||||||
#include <Airports/airport.hxx>
|
#include <Airports/airport.hxx>
|
||||||
#include <Airports/runways.hxx>
|
#include <Airports/runways.hxx>
|
||||||
|
@ -222,18 +225,28 @@ FGTaxiNodeRef FGGroundNetwork::findNearestNode(const SGGeod & aGeod) const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
FGTaxiNodeRef FGGroundNetwork::findNearestNodeOffRunway(const SGGeod& aGeod) const
|
FGTaxiNodeRef FGGroundNetwork::findNearestNodeOffRunway(const SGGeod& aGeod, FGRunway* rwy, double marginM) const
|
||||||
{
|
{
|
||||||
SGVec3d cartPos = SGVec3d::fromGeod(aGeod);
|
FGTaxiNodeVector nodes;
|
||||||
auto node = std::min_element(m_nodes.begin(), m_nodes.end(),
|
const SGLineSegmentd runwayLine(rwy->cart(), SGVec3d::fromGeod(rwy->end()));
|
||||||
[cartPos](const FGTaxiNodeRef& a, const FGTaxiNodeRef& b)
|
const double marginMSqr = marginM * marginM;
|
||||||
{
|
const SGVec3d cartPos = SGVec3d::fromGeod(aGeod);
|
||||||
double aDist = a->getIsOnRunway() ? DBL_MAX : distSqr(cartPos, a->cart());
|
|
||||||
double bDist = b->getIsOnRunway() ? DBL_MAX : distSqr(cartPos, b->cart());
|
|
||||||
return aDist < bDist;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (node == m_nodes.end()) {
|
std::copy_if(m_nodes.begin(), m_nodes.end(), std::back_inserter(nodes),
|
||||||
|
[runwayLine, cartPos, marginMSqr] (const FGTaxiNodeRef& a)
|
||||||
|
{
|
||||||
|
if (a->getIsOnRunway()) return false;
|
||||||
|
return (distSqr(runwayLine, a->cart()) >= marginMSqr);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// find closest of matching nodes
|
||||||
|
auto node = std::min_element(nodes.begin(), nodes.end(),
|
||||||
|
[cartPos](const FGTaxiNodeRef& a, const FGTaxiNodeRef& b)
|
||||||
|
{ return distSqr(cartPos, a->cart()) < distSqr(cartPos, b->cart()); });
|
||||||
|
|
||||||
|
if (node == nodes.end()) {
|
||||||
return FGTaxiNodeRef();
|
return FGTaxiNodeRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,7 @@ public:
|
||||||
FGTaxiNodeRef findNearestNode(const SGGeod& aGeod) const;
|
FGTaxiNodeRef findNearestNode(const SGGeod& aGeod) const;
|
||||||
FGTaxiNodeRef findNearestNodeOnRunway(const SGGeod& aGeod, FGRunway* aRunway = NULL) const;
|
FGTaxiNodeRef findNearestNodeOnRunway(const SGGeod& aGeod, FGRunway* aRunway = NULL) const;
|
||||||
|
|
||||||
FGTaxiNodeRef findNearestNodeOffRunway(const SGGeod& aGeod) const;
|
FGTaxiNodeRef findNearestNodeOffRunway(const SGGeod& aGeod, FGRunway* aRunway, double distanceM) const;
|
||||||
|
|
||||||
FGTaxiSegment *findSegment(unsigned int idx) const;
|
FGTaxiSegment *findSegment(unsigned int idx) const;
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <Airports/runways.hxx>
|
#include <Airports/runways.hxx>
|
||||||
#include <Airports/airport.hxx>
|
#include <Airports/airport.hxx>
|
||||||
#include <Airports/dynamics.hxx>
|
#include <Airports/dynamics.hxx>
|
||||||
|
#include <Airports/groundnetwork.hxx>
|
||||||
#include <AIModel/AIManager.hxx>
|
#include <AIModel/AIManager.hxx>
|
||||||
#include <GUI/MessageBox.hxx>
|
#include <GUI/MessageBox.hxx>
|
||||||
|
|
||||||
|
@ -166,21 +167,28 @@ boost::tuple<SGGeod, double> runwayStartPos(FGRunwayRef runway)
|
||||||
{
|
{
|
||||||
fgSetString("/sim/atc/runway", runway->ident().c_str());
|
fgSetString("/sim/atc/runway", runway->ident().c_str());
|
||||||
double offsetNm = fgGetDouble("/sim/presets/offset-distance-nm");
|
double offsetNm = fgGetDouble("/sim/presets/offset-distance-nm");
|
||||||
|
double startOffset = fgGetDouble("/sim/airport/runways/start-offset-m", 5.0);
|
||||||
|
SGGeod pos = runway->pointOnCenterline(startOffset);
|
||||||
|
|
||||||
if (isMPEnabled() && (fabs(offsetNm) <0.1)) {
|
if (isMPEnabled() && (fabs(offsetNm) <0.1)) {
|
||||||
SG_LOG( SG_GENERAL, SG_WARN, "Requested to start on " << runway->airport()->ident() << "/" <<
|
SG_LOG( SG_GENERAL, SG_WARN, "Requested to start on " << runway->airport()->ident() << "/" <<
|
||||||
runway->ident() << ", MP is enabled so computing hold short position to avoid runway incursion");
|
runway->ident() << ", MP is enabled so computing hold short position to avoid runway incursion");
|
||||||
|
|
||||||
// set this so multiplayer.nas can inform the user
|
FGGroundNetwork* groundNet = runway->airport()->groundNetwork();
|
||||||
fgSetBool("/sim/presets/avoided-mp-runway", true);
|
// add a margin, try to keep the entire aeroplane comfortable off the
|
||||||
|
// runway.
|
||||||
|
double margin = startOffset + (runway->widthM() * 1.5);
|
||||||
|
FGTaxiNodeRef taxiNode = groundNet ? groundNet->findNearestNodeOffRunway(pos, runway, margin) : 0;
|
||||||
|
if (taxiNode) {
|
||||||
|
// set this so multiplayer.nas can inform the user
|
||||||
|
fgSetBool("/sim/presets/avoided-mp-runway", true);
|
||||||
|
return boost::make_tuple(taxiNode->geod(), SGGeodesy::courseDeg(taxiNode->geod(), pos));
|
||||||
|
}
|
||||||
|
|
||||||
double width = runway->widthM();
|
// if we couldn't find a suitable taxi-node, give up. Guessing a position
|
||||||
double offset = fgGetDouble("/sim/airport/runways/start-offset-m", 5.0) + width;
|
// causes too much pain (starting in the water or similar bad things)
|
||||||
SGGeod pos = runway->pointOffCenterline(width * 0.5, -offset);
|
|
||||||
return boost::make_tuple(pos, runway->headingDeg() + 90.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SGGeod pos = runway->pointOnCenterline(fgGetDouble("/sim/airport/runways/start-offset-m", 5.0));
|
|
||||||
return boost::make_tuple(pos, runway->headingDeg());
|
return boost::make_tuple(pos, runway->headingDeg());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue