//------------------------------------------------------------------------------ // getRayIndex() -- //------------------------------------------------------------------------------ int Rwr::getRayIndex(const LCreal az) const { LCreal az1 = lcAepcDeg(az); if (az1 < 0.0) az1 += 360.0; int idx = int( (az1/ getDegreesPerRay()) + 0.5 ); if (idx >= NUM_RAYS || idx < 0) idx = 0; return idx; }
//------------------------------------------------------------------------------ // updateData() - //------------------------------------------------------------------------------ void Adi::updateData(const LCreal dt) { // update our base class first BaseClass::updateData(dt); // drive our adi toward the actual pitch, from our current pitch, no faster // than our MAX_RATE (this allows for greater fidelity, simulates an analog adi) LCreal delta = 0; delta = alim (lcAepcDeg(pitch - curTheta), maxRate * dt); curTheta = lcAepcDeg(curTheta + delta); // now do the same thing for roll delta = alim (lcAepcRad(roll - curPhi), maxRate * dt); curPhi = lcAepcRad(curPhi + delta); // get our table, and do the linear interpolation ourself setInstVal(curTheta); scaledPitch = getInstValue(); }
//------------------------------------------------------------------------------ // updateData() -- update non time-critical stuff here //------------------------------------------------------------------------------ void TestElectronic::updateData(const LCreal dt) { BaseClass::updateData(dt); updateTestValues(dt); // current heading / current heading bug { // max rate here is 120 degs / second LCreal delta = alim(lcAepcDeg(heading - curHdg), 120 * dt); curHdg = lcAepcDeg(curHdg + delta); // now figure our heading bug delta = alim(lcAepcDeg(headingBug - curBug), 120 * dt); curBug = lcAepcDeg(curBug + delta); if (navMode == ARC_MODE) { // we either move it to the left or right, depending on how far // off our slew is. LCreal diff = lcAepcDeg(curHdg - curBug); LCreal moveX = -1.8f; if (diff >= -36 && diff < 36) { if (diff > 0) moveX = 1.53f; else moveX = -1.8f; } int tempCurBug = static_cast<int>(curBug); if (tempCurBug < 0) tempCurBug += 360; // heading bug readout value and x position. send("bugro", UPDATE_VALUE, tempCurBug, hdgBugROSD); send("headingbugro", UPDATE_VALUE, moveX, hdgBugROMoveXSD); // heading bug actual position send("headingbug", UPDATE_VALUE6, heading - curBug, headingBugSD); } } // distance data / DME { // are we a distance type or DME type? bool distType = true; // initial type is DME bool distVis = true; // initial visibility is true LCreal curDist = alim(dist, 999.9f); // current distance to DME if (navSource == PRIMARY) { // valid DME makes our label visible distVis = dmeValid; if (navType == INAV) distType = false; } else if (navSource == SECONDARY) { // valid DME makes our label visible distVis = secDmeValid; if (secNavType == INAV) distType = false; else distVis = true; } send("distlabel", SELECT, distType, distTypeSD); send("distval", SET_VISIBILITY, distVis, distVisSD); send("distval", UPDATE_VALUE, curDist, curDistSD); } // course data { // which course pointer are we using? send("whichcourseptr", SELECT, navSource, whichCrsPtrSD); int curIntCourse = 0; LCreal tempCDI = 0; LCreal tempCourse = 0; // primary nav course if (navSource == PRIMARY) { curIntCourse = nint(course); tempCDI = cdi; tempCourse = course; } // secondary nav course else { curIntCourse = nint(secCourse); tempCDI = secCdi; tempCourse = secCourse; } if (curIntCourse < 0) curIntCourse += 360; // send the course readout send("course", UPDATE_VALUE, curIntCourse, courseSD); // here is the course deviation LCreal delta = alim (lcAepcDeg(tempCDI - curCdi), 4 * dt); curCdi = alim (curCdi + delta, 2.0); // now find our inches to translate the cdi LCreal cdiInch = curCdi * 0.43f; // now figure our course slew delta = alim(lcAepcDeg(tempCourse - curCourse), 120 * dt); curCourse = (lcAepcDeg(curCourse + delta)); // ok, do our color determination for the course pointer - primary first if (navSource == PRIMARY) { // dealing with our primary course pointer here bool vis = true; if (navMode == MAP_MODE || navMode == DECLUTTER) vis = false; send("primarycoursepointer", SET_VISIBILITY, vis, primaryCrsVisSD); // course pointer deviation and rotation send("primarycoursedev", UPDATE_VALUE, cdiInch, priCourseDevSD); send("primarycoursepointer", UPDATE_VALUE6, heading - curCourse, crsPntrSD); // course pointer color Basic::String* string = new Basic::String("white"); if (navType == VORTAC) { if ((vhfReceive && !(vhfDIC || vhfLGS)) || (vhfLocValid && vhfLGS)) string->setStr("green"); else string->setStr("yellow"); } else { if (dmeValid) string->setStr("green"); else string->setStr("yellow"); } send("primarycoursepointer", SET_COLOR, string->getString(), priCrsPtrColorSD); // get rid of our string string->unref(); } else { // secondary course pointer bool vis = true; if (secNavMode == MAP_MODE || secNavMode == DECLUTTER) vis = false; send("secondarycoursepointer", SET_VISIBILITY, vis, secondaryCrsVisSD); // course pointer deviation and rotation send("secondarycoursedev", UPDATE_VALUE, cdiInch, secCourseDevSD); send("secondarycoursepointer", UPDATE_VALUE2, curCourse - heading, secCrsPntrSD); // course pointer color Basic::String* string = new Basic::String("white"); if (secNavType == VORTAC) { if ((secVhfReceive && !(secVhfDIC || secVhfLGS)) || (secVhfLocValid && secVhfLGS)) string->setStr("green"); else string->setStr("yellow"); } else { if (secDmeValid) string->setStr("green"); else string->setStr("yellow"); } send("secondarycoursepointer", SET_COLOR, string->getString(), secCrsPtrColorSD); // get rid of our string string->unref(); } } // our data readouts (TTG, Gs, etc...) { // which readout are we using send("whichlabel", SELECT, readoutMode, roLabelSD); // send which readout we are going to use send("whichreadout", SELECT, readoutMode, roWhichSD); // first readout, which is our time to go if (readoutMode == ND_TTG) { LCreal curTTG = timeToGo / 60; send("ttg", UPDATE_VALUE, curTTG, ttgSD); } // ground speed, drift angle, drift angle side. else if (readoutMode == ND_GSP) { // ground speed send("groundspeed", UPDATE_VALUE, groundSpeed, groundSpeedSD); // drift angle send("driftangle", UPDATE_VALUE, abs(driftAngle), driftAngleSD); if (driftAngle < 0) send("driftangleside", SELECT, true, driftAngSideSD); else send("driftangleside", SELECT, false, driftAngSideSD); } // true air speed else if (readoutMode == ND_TAS) { int curTAS = nintd(trueAirSpeed * Basic::LinearVelocity::FPS2KTSCC); send("trueairspeed", UPDATE_VALUE, curTAS, trueAirSpeedSD); } // elapsed time else if (readoutMode == ND_ET) { int hour = static_cast<int>(elapsedTime / 3600); bool isMin = false; // default to show hours if (hour < 1) { isMin = true; // show in minutes send("elapsedtimemin", UPDATE_VALUE, elapsedTime, elapsedTimeSD); } else send("elapsedtimehour", UPDATE_VALUE, elapsedTime, elapsedTimeHRSD); // send which readout send("whichelapsedtimero", SELECT, isMin, whichETSD); } // wind speed, direction, and drift angle (again) else if (readoutMode == ND_WIND) { // wind direction send("winddirection", UPDATE_VALUE, windDir, windDirectionSD); // wind speed send("windspeed", UPDATE_VALUE, windSpeed, windSpeedSD); // wind drift angle (same as drift angle for test purposes) send("driftanglewind", UPDATE_VALUE, abs(driftAngle), driftAngleWindSD); bool left = false; // false is right side, true is left // drift angle side if (driftAngle < 0) left = true; send("driftanglewindside", SELECT, left, whichSideDAWindSD); } } // bearing readouts { // determine the source of our bearing int brgSrc = 1; // default to INAV if (navSource == PRIMARY) { if (navType == VORTAC) brgSrc = 2; // primary vortac else if (navType == TACAN) brgSrc = 3; // primary tacan send("bearingro", UPDATE_VALUE, bearing, brgROSD); } else { if (secNavType == VORTAC) brgSrc = 4; // secondary vortac else brgSrc = 5; // secondary tacan send("bearingro", UPDATE_VALUE, secBearing, secBrgROSD); } send("bearingsource", SELECT, brgSrc, brgSourceSD); } // glide slope { LCreal gsDev = static_cast<LCreal>(alim (gsDots, 2.1f) * 0.35f); send("glideslopedev", UPDATE_VALUE2, gsDev, glideSlopeSD); } // compass { // let's do decentered for both, and hsi mode will just set displacement to 0 send("compass", UPDATE_VALUE6, false, centeredSD); // send our compass heading send("compass", UPDATE_VALUE, curHdg, compassHdgSD); } // primary and secondary readout indicators (with asterisk) { // first of all, which position is the asterisk going in (primary or secondary?) send("whichnavsource", SELECT, navSource, whichNavSrcSD); // primary nav source selection int primaryPos = 1; // 1 is INAV if (navType == VORTAC) { // pilot if (loc == PILOT) { if (vhfLGS) primaryPos = 2; else primaryPos = 3; } // copilot else { if (vhfLGS) primaryPos = 4; else primaryPos = 5; } } else if (navType == TACAN) primaryPos = 6; send("whichprimaryreadout", SELECT, primaryPos, primaryPosSD); // now do our secondary source selections int secondaryPos = 1; if (secNavType == VORTAC) { // pilot if (loc == PILOT) { if (secVhfLGS) secondaryPos = 2; else secondaryPos = 3; } // copilot else { if (secVhfLGS) secondaryPos = 4; else secondaryPos = 5; } } else if (secNavType == TACAN) secondaryPos = 6; send("whichsecondaryreadout", SELECT, secondaryPos, secondaryPosSD); } // TO / FROM arrow - HSI mode only { LCreal toFrom = 0; if (navSource == PRIMARY) toFrom = 1 - lcAbs(lcAepcDeg(bearing - course)) / 90; else toFrom = 1 - lcAbs(lcAepcDeg(secBearing - secCourse)) / 90; LCreal delta = alim(toFrom - curToFrom, dt); curToFrom = alim(curToFrom + delta, 0.65f); // if we are positive, we are to, negative, from bool whichToFrom = (curToFrom > 0); send("toorfrom", SELECT, whichToFrom, toOrFromSD); // now send down where to translate send("tofrom", UPDATE_VALUE2, curToFrom, toFromSD); } }
//------------------------------------------------------------------------------ // getRayAzimuth() -- //------------------------------------------------------------------------------ LCreal Rwr::getRayAzimuth(const int idx) const { LCreal az = getDegreesPerRay() * LCreal(idx); return lcAepcDeg(az); }
//------------------------------------------------------------------------------ // hsv2rgb() -- converts a Hue, Saturation, Value (HSV) color value to an // Red, Gree, Blue (RGB) value. // // This code is based on '/usr/people/4Dgifts/iristools/libgutil/colormod.c' //------------------------------------------------------------------------------ void Hsv::hsv2rgb(osg::Vec3& rgb, const osg::Vec3& hsv) { // local HSV values LCreal h = lcAepcDeg(hsv[HUE]); if (h < 0.0f) h += 360.0f; LCreal s = hsv[SATURATION]; LCreal v = hsv[VALUE]; if (s != 0.0) { // The max hue value is the same as the min hue value. if (h == 360.0f) h = 0.0f; h /= 60.0f; // computer some parameters //int i = ffloor(h); int i = static_cast<int>(h); LCreal f = h - static_cast<LCreal>(i); LCreal p = v * (1.0f - s); LCreal q = v * (1.0f - (s * f)); LCreal t = v * (1.0f - (s * (1.0f - f))); switch (i) { case 0 : { // when hue is >= red and < yellow rgb[RED] = v; rgb[GREEN] = t; rgb[BLUE] = p; } break; case 1 : { // when hue is >= yellow and < green rgb[RED] = q; rgb[GREEN] = v; rgb[BLUE] = p; } break; case 2 : { // when hue is >= green and < cyan rgb[RED] = p; rgb[GREEN] = v; rgb[BLUE] = t; } break; case 3 : { // when hue is >= cyan and < blue rgb[RED] = p; rgb[GREEN] = q; rgb[BLUE] = v; } break; case 4 : { // when hue is >= blue and < magenta rgb[RED] = t; rgb[GREEN] = p; rgb[BLUE] = v; } break; case 5 : { // when hue is >= magenta and < red rgb[RED] = v; rgb[GREEN] = p; rgb[BLUE] = q; } break; } } else { // when saturation is zero, the color is gray of intensity 'v'. rgb[RED] = v; rgb[GREEN] = v; rgb[BLUE] = v; } }