/// Draws waypoints. static int RouteDrawCallback(XPLMDrawingPhase inPhase, int inIsBefore, void * inRefcon) { float px = XPLMGetDataf(planeXref); float py = XPLMGetDataf(planeYref); float pz = XPLMGetDataf(planeZref); // Convert to local for (size_t i = 0; i < numWaypoints; ++i) { Waypoint* g = &waypoints[i]; LocalPoint* l = &localPoints[i]; XPLMWorldToLocal(g->latitude, g->longitude, g->altitude, &l->x, &l->y, &l->z); } // Draw posts glColor3f(1.0F, 1.0F, 1.0F); glBegin(GL_LINES); for (size_t i = 0; i < numWaypoints; ++i) { LocalPoint* l = &localPoints[i]; glVertex3f((float)l->x, (float)l->y, (float)l->z); glVertex3f((float)l->x, -1000.0F, (float)l->z); } glEnd(); // Draw route glColor3f(1.0F, 0.0F, 0.0F); glBegin(GL_LINE_STRIP); for (size_t i = 0; i < numWaypoints; ++i) { LocalPoint* l = &localPoints[i]; glVertex3f((float)l->x, (float)l->y, (float)l->z); } glEnd(); // Draw markers glColor3f(1.0F, 1.0F, 1.0F); for (size_t i = 0; i < numWaypoints; ++i) { LocalPoint* l = &localPoints[i]; float xoff = (float)l->x - px; float yoff = (float)l->y - py; float zoff = (float)l->z - pz; float d = sqrtf(xoff*xoff + yoff*yoff + zoff*zoff); gl_drawCube((float)l->x, (float)l->y, (float)l->z, d); } return 1; }
float myFlightLoopCallback(float inElapsedSinceLastCall, float inElapsedTimeSinceLastFlightLoop, int inCounter, void * inRefcon) { if(gPluginEnabled && gnsOpened) { #if 0 //FIXME if(autopilotConnected) { XPLMSetDatai(g_override_autopilot_ref, 1); XPLMSetDatai(g_autopilot_state_ref, 512); //see doc (HNAV engaged) override_gps = 1;//;pIntf->override_gps; XPLMSetDatai(g_override_gps_ref, override_gps); gps_fromto = 1; XPLMSetDatai(g_gps_fromto_ref, gps_fromto); gps_course_degtm = pIntf->dtk; XPLMSetDataf(g_gps_course_degtm_ref, gps_course_degtm); hsi_obs_deg_mag_pilot = pIntf->dtk; XPLMSetDataf(g_hsi_obs_deg_mag_pilot_ref, hsi_obs_deg_mag_pilot); XPLMSetDataf(g_gps_hdef_dot_ref, pIntf->cdi_horizontal_offtrack); } else { XPLMSetDatai(g_override_autopilot_ref, 0); } #endif //Set the COM frequencies XPLMSetDatai(g_com1_active_ref, gGNSx30Proxy.getCOMActiveFrequency()/10); XPLMSetDatai(g_com1_standby_ref, gGNSx30Proxy.getCOMStandbyFrequency()/10); XPLMSetDatai(g_nav1_active_ref, gGNSx30Proxy.getNAVActiveFrequency()/10); XPLMSetDatai(g_nav1_standby_ref, gGNSx30Proxy.getNAVStandbyFrequency()/10); latitude = XPLMGetDatad(g_latitude_ref); longitude = XPLMGetDatad(g_longitude_ref); heading = XPLMGetDataf(g_heading_ref); groundspeed = XPLMGetDataf(g_groundspeed_ref); elevation = (float)XPLMGetDatad(g_elevation_ref); vert_speed = XPLMGetDataf(g_vert_speed_ref); if(heading > 180.0f) // from 0 t pi and from -pi to 0 heading = -360.0f + heading; gGNSx30Proxy.setGPSInfo(latitude * PI / 180.0f, // rad longitude * PI / 180.0f, // rad groundspeed, heading*PI/180.0f, vert_speed, elevation); } return gUpdateInterval; //update every 0.01 sec }
float SmoothSailingCallback( float inElapsedSinceLastCall, float inElapsedTimeSinceLastFlightLoop, int inCounter, void *inRefcon) { /* get altitude - it's used in a number of places */ float alt_agl = XPLMGetDataf( ref_alt_agl ); float alt_msl = XPLMGetDataf( ref_alt_msl ); /* only reset time if we think there's a reason to do it (set elsewhere) * and if the plane is not in the air */ if( reset_time && alt_agl < 1 ) { resetTime(); } else { reset_time = false; } setVisibility(); setCloudBase( alt_agl, alt_msl ); setWind( alt_agl, alt_msl ); setTurbulence(); return CALLBACK_INTERVAL; }
/* * MyDrawingWindowCallback * * This callback does the work of drawing our window once per sim cycle each time * it is needed. It dynamically changes the text depending on the saved mouse * status. Note that we don't have to tell X-Plane to redraw us when our text * changes; we are redrawn by the sim continuously. * */ void MyDrawWindowCallback( XPLMWindowID inWindowID, void * inRefcon) { int left, top, right, bottom; float color[] = { 1.0, 1.0, 1.0 }; /* RGB White */ int xpndr_mode; float alt_agl, grnd_spd; char buffer[50]; xpndr_mode = XPLMGetDatai( ref_xpndr_mode ); alt_agl = XPLMGetDataf( ref_alt_agl ); grnd_spd = XPLMGetDataf( ref_grnd_spd ); /* First we get the location of the window passed in to us. */ XPLMGetWindowGeometry(inWindowID, &left, &top, &right, &bottom); /* We now use an XPLMGraphics routine to draw a translucent dark * rectangle that is our window's shape. */ XPLMDrawTranslucentDarkBox(left, top, right, bottom); /* Finally we draw the text into the window, also using XPLMGraphics * routines. The NULL indicates no word wrapping. */ sprintf(buffer, "xpndr_mode: %d", xpndr_mode); XPLMDrawString(color, left + 5, top - 20, buffer, NULL, xplmFont_Basic); sprintf(buffer, "alt_agl: %d", (int)floor(alt_agl)); XPLMDrawString(color, left + 5, top - 40, buffer, NULL, xplmFont_Basic); sprintf(buffer, "grnd_spd: %d", (int)floor(grnd_spd)); XPLMDrawString(color, left + 5, top - 60, buffer, NULL, xplmFont_Basic); XPLMDrawString(color, left + 5, top - 80, debug_string, NULL, xplmFont_Basic); }
float XPlaneInterface::getStaticAirTemperatureKelvin() { float value = XPLMGetDataf(findDataRefByCode(TEMPERATURE_AMBIENT)); // Convert to kelvin return value + CELSIUS_TO_KELVIN_FACTOR; }
void FloatDataRef::updateValue() { float newValue = XPLMGetDataf(_ref); if(_value != newValue) { _value = newValue; emit changed(this); } }
void setTurbulence( void ) { /* the tailwind just rockets us op to 0.5 turbulence, not okay */ /* i think .01 is the min? */ /* TODO: make this configurable */ if( XPLMGetDataf( ref_wind_turb0 ) > 0.1 ) { XPLMSetDataf( ref_wind_turb0, 0.1 ); } }
void setCloudBase( float alt_agl, float alt_msl ) { float cloud_base_msl = XPLMGetDataf( ref_cloud_base0 ); float ground_level = alt_msl - alt_agl; float cloud_base_agl = cloud_base_msl - ground_level; float cloud_tops_msl = XPLMGetDataf( ref_cloud_tops0 ); /* find the difference betwee the lowest cloud layer and what we want, * then apply that difference to all cloud layers */ float delta = config_min_cloud_base - cloud_base_agl; sprintf( debug_string, "min: %f, base %f, detla %f", config_min_cloud_base, cloud_base_agl, delta ); /* only set clouds if they're above the plane */ if( cloud_tops_msl > alt_msl && ( delta > 0 ) ) { XPLMSetDataf( ref_cloud_base0, cloud_base_msl + delta ); XPLMSetDataf( ref_cloud_tops0, XPLMGetDataf( ref_cloud_tops0 ) + delta ); XPLMSetDataf( ref_cloud_base1, XPLMGetDataf( ref_cloud_base1 ) + delta ); XPLMSetDataf( ref_cloud_tops1, XPLMGetDataf( ref_cloud_tops1 ) + delta ); XPLMSetDataf( ref_cloud_base2, XPLMGetDataf( ref_cloud_base2 ) + delta ); XPLMSetDataf( ref_cloud_tops2, XPLMGetDataf( ref_cloud_tops2 ) + delta ); } }
// ***************** HDG Button and light ******************* void process_hdg_button() { if (loaded737 == 1) { if (multires > 0) { if (testbit(multibuf, HDG_BUTTON)) { XPLMCommandOnce(x737mcp_hdg_toggle); lastappos = 1; } } // Always match x737 glareshield LED switch (XPLMGetDatai(x737mcp_hdg_led)) { case 1: btnleds |= (1<<1); break; case 0: btnleds &= ~(1<<1); break; } } else { if (multires > 0) { if(testbit(multibuf,HDG_BUTTON)) { if(xpanelsfnbutton == 1) { rhdgf = XPLMGetDataf(MHdg); XPLMSetDataf(ApHdg, rhdgf); } if(xpanelsfnbutton == 0) { XPLMCommandOnce(ApHdgBtn); lastappos = 1; } } } switch(XPLMGetDatai(ApHdgStat)){ case 2: btnleds |= (1<<1); // * set bit 1 in btnleds to 1 * break; case 1: if (flashon == 1) { btnleds |= (1<<1); // * set bit 1 in btnleds to 1 * }else{ btnleds &= ~(1<<1); // * clear bit 1 in btnleds to 0 * } break; case 0: btnleds &= ~(1<<1); // * clear bit 1 in btnleds to 0 * break; } if (XPLMGetDatai(ApMstrStat) == 0) { btnleds &= ~(1<<1); // * clear bit 1 in btnleds to 0 * } } }
float MyFlightLoopCallback( float inElapsedSinceLastCall, float inElapsedTimeSinceLastFlightLoop, int inCounter, void * inRefcon) { /* The actual callback. First we read the sim's time and the data. */ float elapsed = XPLMGetElapsedTime(); float lat = XPLMGetDataf(gPlaneLat); float lon = XPLMGetDataf(gPlaneLon); float el = XPLMGetDataf(gPlaneEl); float vis = XPLMGetDataf(gPlaneVis); /* Write the data to a file. */ fprintf(gOutputFile, "Vis=%f,Time=%f,lat=%f,lon=%f,el=%f.\n",vis,elapsed, lat, lon, el); XPLMSetDataf(gPlaneVis, vis_amount); /* Return 1.0 to indicate that we want to be called again in 1 second. */ return 1.0; }
void GyroModel::setEQOff(){ if(XPlaneData->equalizer()==1) { float nav1=XPLMGetDataf(XPLMFindDataRef("sim/cockpit2/radios/actuators/nav1_obs_deg_mag_pilot")); float nav2=XPLMGetDataf(XPLMFindDataRef("sim/cockpit2/radios/actuators/nav2_obs_deg_mag_pilot")); if(nav2<nav1){ XPLMSetDataf(XPLMFindDataRef("sim/cockpit2/radios/actuators/nav2_obs_deg_mag_pilot"),XPLMGetDataf(XPLMFindDataRef("sim/cockpit2/radios/actuators/nav2_obs_deg_mag_pilot"))+0.5); } else { XPLMSetDataf(XPLMFindDataRef("sim/cockpit2/radios/actuators/nav2_obs_deg_mag_pilot"),XPLMGetDataf(XPLMFindDataRef("sim/cockpit2/radios/actuators/nav2_obs_deg_mag_pilot"))-0.5); } if(round(nav2)==round(nav1)) { XPlaneData->setEqualizerOff(); } } }
void resetTime() { float local_time_seconds, new_zulu_seconds; /* in order for the clock to be set right, we need to make sure we're using * system time initially to get local time, then turn off use system time before * changing the time -- using system time is set in the message handler */ local_time_seconds = XPLMGetDataf( ref_local_time ); new_zulu_seconds = XPLMGetDataf( ref_zulu_time ); if( local_time_seconds > config_late_time_seconds ) { new_zulu_seconds -= config_time_rollback_seconds; } else if( local_time_seconds < config_early_time_seconds ) { new_zulu_seconds += config_time_push_forward_seconds; } /* always turn off system time and always change it to make sure the clock gets set correctly */ XPLMSetDatai( ref_use_sys_time, 0 ); XPLMSetDataf( ref_zulu_time, new_zulu_seconds ); reset_time = false; }
void GyroModel::addYawDeviation() { cageGyro.yaw = cageGyro.yaw+0.000111111; // 15p alatt 3 fok XPLMSetDataf(XPLMFindDataRef("sim/cockpit2/radios/actuators/nav2_obs_deg_mag_pilot"),XPLMGetDataf(XPLMFindDataRef("sim/cockpit2/radios/actuators/nav2_obs_deg_mag_pilot"))+0.000055555); // 30p alatt 3 fok }
float XPlaneInterface::getBankAngleDegrees() { return XPLMGetDataf(findDataRefByCode(BANK_ANGLE)); }
float XPlaneInterface::getPitchAttitudeDegrees() { return XPLMGetDataf(findDataRefByCode(PITCH_ATTITUDE)); }
float XPlaneInterface::getIASKn() { return XPLMGetDataf(findDataRefByCode(SPEED_IAS)); }
float XPlaneInterface::getCurrentPressureInHg() { return XPLMGetDataf(findDataRefByCode(BAROMETER_CURRENT_PRESSURE)); }
// ***************** HDG Switch Position ******************* void process_hdg_switch() { if(testbit(multibuf,HDG_SWITCH)) { multiseldis = 3; upaphdgf = XPLMGetDataf(ApHdg); upaphdg = (int)(upaphdgf); if(testbit(multibuf,ADJUSTMENT_UP)) { hdgdbncinc++; if (hdgdbncinc > multispeed) { if(xpanelsfnbutton == 1) { if (loaded737 == 1) { XPLMCommandOnce(x737mcp_hdg_up_fast); } else { upaphdg = upaphdg + multimul; } hdgdbncinc = 0; } if(xpanelsfnbutton == 0) { if (loaded737 == 1) { XPLMCommandOnce(x737mcp_hdg_up); } else { upaphdg = upaphdg + 1; } hdgdbncinc = 0; } } } if(testbit(multibuf,ADJUSTMENT_DN)) { hdgdbncdec++; if (hdgdbncdec > multispeed) { if(xpanelsfnbutton == 1) { if (loaded737 == 1) { XPLMCommandOnce(x737mcp_hdg_down_fast); } else { upaphdg = upaphdg - multimul; } hdgdbncdec = 0; } if(xpanelsfnbutton == 0) { if (loaded737 == 1) { XPLMCommandOnce(x737mcp_hdg_down); } else { upaphdg = upaphdg - 1; } hdgdbncdec = 0; } } } if (loaded737 != 1) { if(upaphdg > 360){ upaphdg = 1; } if(upaphdg < 0){ upaphdg = 359; } upaphdgf = upaphdg; XPLMSetDataf(ApHdg, upaphdgf); } } }
float XPlaneInterface::getAOADegrees() { float value = XPLMGetDataf(findDataRefByCode(AOA_ANGLE)); return value; }
float XPlaneInterface::getGNormal() { return XPLMGetDataf(findDataRefByCode(G_NORMAL)); }
void GetGPSData(void) { union longbbbb Temp4; union intbb Temp2; int LocalDays = XPLMGetDatai(drLocalDays); float LocalSecsFloat = XPLMGetDataf(drLocalSecs) * 1000; LocalDays += 5; int Week = (int)(LocalDays / 7) + 1564; LocalDays = (LocalDays % 7); Week = (Week * 10) + LocalDays; int LocalSecsInt = (int)LocalSecsFloat + (LocalDays * 86400000); LocalSecsFloat = (LocalSecsFloat - (int)LocalSecsFloat) * 1000000; Temp2.BB = Week; Store2LE(&NAV_SOL[14], Temp2); Temp4.WW = LocalSecsInt; Store4LE(&NAV_SOL[6], Temp4); Store4LE(&NAV_DOP[6], Temp4); Store4LE(&NAV_POSLLH[6], Temp4); Store4LE(&NAV_VELNED[6], Temp4); Temp4.WW = (int)LocalSecsFloat; Store4LE(&NAV_SOL[10], Temp4); double latitude = XPLMGetDataf(drLat); double longitude = XPLMGetDataf(drLon); double elevation = XPLMGetDataf(drElev); double local_x = XPLMGetDataf(drLocal_x); double local_y = XPLMGetDataf(drLocal_y); double local_z = XPLMGetDataf(drLocal_z); double local_vx = XPLMGetDataf(drLocal_vx); double local_vy = XPLMGetDataf(drLocal_vy); double local_vz = XPLMGetDataf(drLocal_vz); Temp4.WW = (int)(local_vx * 100); Store4LE(&NAV_VELNED[14], Temp4); Temp4.WW = (int)(local_vy * -100); Store4LE(&NAV_VELNED[18], Temp4); Temp4.WW = (int)(local_vz * -100); Store4LE(&NAV_VELNED[10], Temp4); Temp4.WW = (int)(XPLMGetDataf(drAirSpeedTrue) * 100); Store4LE(&NAV_VELNED[22], Temp4); Temp4.WW = (int)(XPLMGetDataf(drGroundSpeed) * 100); Store4LE(&NAV_VELNED[26], Temp4); Temp4.WW = (int)(XPLMGetDataf(drHeading) * 100000); Store4LE(&NAV_VELNED[30], Temp4); Temp4.WW = (int)(latitude * 10000000); Store4LE(&NAV_POSLLH[14], Temp4); Temp4.WW = (int)(longitude * 10000000); Store4LE(&NAV_POSLLH[10], Temp4); Temp4.WW = (int)(elevation * 1000); Store4LE(&NAV_POSLLH[18], Temp4); Store4LE(&NAV_POSLLH[22], Temp4); double ac_pos_lat, ac_pos_lon, ac_pos_elev; double ac_vel_lat, ac_vel_lon, ac_vel_elev; // Get AC pos in LLA XPLMLocalToWorld( local_x, local_y, local_z, &ac_pos_lat, &ac_pos_lon, &ac_pos_elev ); // Get AC pos + velocity vector in LLA XPLMLocalToWorld( local_x + local_vx, local_y + local_vy, local_z + local_vz, &ac_vel_lat, &ac_vel_lon, &ac_vel_elev ); // convert to ECEF LLAtoECEF(ac_pos_lat, ac_pos_lon, ac_pos_elev, local_x, local_y, local_z); LLAtoECEF(ac_vel_lat, ac_vel_lon, ac_vel_elev, local_vx, local_vy, local_vz); // AC pos stays as is // subtract to get velocity vector in ECEF local_vy -= local_y; local_vx -= local_x; local_vz -= local_z; Temp4.WW = (int)(local_x * 100); Store4LE(&NAV_SOL[18], Temp4); Temp4.WW = (int)(local_y * 100); Store4LE(&NAV_SOL[22], Temp4); Temp4.WW = (int)(local_z * 100); Store4LE(&NAV_SOL[26], Temp4); Temp4.WW = (int)(local_vx * 100); Store4LE(&NAV_SOL[34], Temp4); Temp4.WW = (int)(local_vy * 100); Store4LE(&NAV_SOL[38], Temp4); Temp4.WW = (int)(local_vz * 100); Store4LE(&NAV_SOL[42], Temp4); CalculateChecksum(NAV_SOL); SendToComPort(sizeof(NAV_SOL),NAV_SOL); CalculateChecksum(NAV_DOP); SendToComPort(sizeof(NAV_DOP),NAV_DOP); CalculateChecksum(NAV_POSLLH); SendToComPort(sizeof(NAV_POSLLH),NAV_POSLLH); CalculateChecksum(NAV_VELNED); SendToComPort(sizeof(NAV_VELNED),NAV_VELNED); }
// ***************** ALT Switch Position ******************* void process_alt_switch() { if(testbit(multibuf,ALT_SWITCH)) { multiseldis = 1; upapaltf = XPLMGetDataf(ApAlt); upapalt = (int)(upapaltf); if(testbit(multibuf,ADJUSTMENT_UP)) { altdbncinc++; if (altdbncinc > multispeed) { if(xpanelsfnbutton == 1) { upapalt = upapalt + 1000; upapalt = (upapalt / 1000); upapalt = (upapalt * 1000); altdbncinc = 0; } if (xpanelsfnbutton == 0) { upapalt = upapalt + 100; upapalt = (upapalt / 100); upapalt = (upapalt * 100); altdbncinc = 0; } } } if(testbit(multibuf,ADJUSTMENT_DN)) { altdbncdec++; if (altdbncdec > multispeed) { if(xpanelsfnbutton == 1) { if (upapalt >= 1000){ upapalt = upapalt - 1000; } if(upapalt > 100){ upapalt = (upapalt / 100); upapalt = (upapalt * 100); } altdbncdec = 0; } if (xpanelsfnbutton == 0) { if (upapalt >= 100){ upapalt = upapalt - 100; } if(upapalt > 100){ upapalt = (upapalt / 100); upapalt = (upapalt * 100); } altdbncdec = 0; } } } upapaltf = upapalt; if (loaded737 == 1) { XPLMSetDataf(x737mcp_alt, upapaltf); } else { XPLMSetDataf(ApAlt, upapaltf); } upapvsf = XPLMGetDataf(ApVs); upapvs = (int)(upapvsf); if (upapvs < 0){ upapvs = (upapvs * -1); neg = 1; } else { neg = 0; } } }
// ***************** APR Button and light ******************* void process_apr_button() { if (loaded737 == 1) { if (multires > 0) { if (testbit(multibuf, APR_BUTTON)) { XPLMCommandOnce(x737mcp_app_toggle); lastappos = 1; } } // Always match x737 glareshield LED switch (XPLMGetDatai(x737mcp_app_led)) { case 1: btnleds |= (1<<6); break; case 0: btnleds &= ~(1<<6); break; } } else if (aprbuttonremap == 1){ if (multires > 0) { if(testbit(multibuf,APR_BUTTON)) { XPLMCommandOnce(AprButtonRemapableCmd); lastappos = 1; } } switch(XPLMGetDatai(ApAprStat)){ case 2: btnleds |= (1<<6); // * set bit 6 in btnleds to 1 * break; case 1: if (flashon == 1) { btnleds |= (1<<6); // * set bit 6 in btnleds to 1 * }else{ btnleds &= ~(1<<6); // * clear bit 6 in btnleds to 0 * } break; case 0: btnleds &= ~(1<<6); // * clear bit 6 in btnleds to 0 * break; } } else { if (multires > 0) { if(testbit(multibuf,APR_BUTTON)) { if(xpanelsfnbutton == 1) { rhdgf = XPLMGetDataf(MHdg); XPLMSetDataf(ApCrs, rhdgf); } if(xpanelsfnbutton == 0) { XPLMCommandOnce(ApAprBtn); lastappos = 1; } } } switch(XPLMGetDatai(ApAprStat)){ case 2: btnleds |= (1<<6); // * set bit 6 in btnleds to 1 * break; case 1: if (flashon == 1) { btnleds |= (1<<6); // * set bit 6 in btnleds to 1 * }else{ btnleds &= ~(1<<6); // * clear bit 6 in btnleds to 0 * } break; case 0: btnleds &= ~(1<<6); // * clear bit 6 in btnleds to 0 * break; } } }
// ***************** VS Switch Position ******************* void process_vs_switch() { if(testbit(multibuf,VS_SWITCH)) { multiseldis = 1; upapvsf = XPLMGetDataf(ApVs); upapvs = (int)(upapvsf); if(testbit(multibuf,ADJUSTMENT_UP)) { vsdbncinc++; if (vsdbncinc > multispeed) { n = multimul; if (xpanelsfnbutton == 1) { if (loaded737 == 1) { XPLMCommandOnce(x737mcp_vvi_up_fast); } else { while (n>0) { //XPLMCommandOnce(ApVsUp); upapvs = upapvs + 100; --n; } } vsdbncinc = 0; } if (xpanelsfnbutton == 0) { if (loaded737 == 1) { XPLMCommandOnce(x737mcp_vvi_up); } else if (apvsupremap == 1) { XPLMCommandOnce(ApVsUpRemapableCmd); } else { //XPLMCommandOnce(ApVsUp); upapvs = upapvs + 100; } vsdbncinc = 0; } } } if(testbit(multibuf,ADJUSTMENT_DN)) { vsdbncdec++; if (vsdbncdec > multispeed) { n = multimul; if(xpanelsfnbutton == 1) { if (loaded737 == 1) { XPLMCommandOnce(x737mcp_vvi_down_fast); } else { while (n>0) { //XPLMCommandOnce(ApVsUp); upapvs = upapvs - 100; --n; } } } vsdbncdec = 0; if(xpanelsfnbutton == 0) { if (loaded737 == 1){ XPLMCommandOnce(x737mcp_vvi_down); } else if (apvsdnremap == 1) { XPLMCommandOnce(ApVsDnRemapableCmd); } else { //XPLMCommandOnce(ApVsUp); upapvs = upapvs - 100; } vsdbncdec = 0; } } } upapvsf = upapvs; XPLMSetDataf(ApVs, upapvsf); upapaltf = XPLMGetDataf(ApAlt); upapvsf = XPLMGetDataf(ApVs); upapalt = (int)(upapaltf); upapvs = (int)(upapvsf); if (upapvs < 0){ upapvs = (upapvs * -1); neg = 1; } else { neg = 0; } } }
// ***************** CRS Switch Position ******************* void process_crs_switch() { float cur_apcrsf = 0; int cur_apcrs = 0; // if the toggle is selected, use nav2, otherwise, nav1 XPLMDataRef crs_dataref = !xpanelscrstoggle ? ApCrs : ApCrs2; if(testbit(multibuf,CRS_SWITCH)) { multiseldis = 4; upapcrsf = XPLMGetDataf(ApCrs); upapcrs = (int)(upapcrsf); // get the appropriate course setting depending on if the toggle is down cur_apcrsf = XPLMGetDataf(crs_dataref); cur_apcrs = (int)(cur_apcrsf); if(testbit(multibuf,ADJUSTMENT_UP)) { crsdbncinc++; if (crsdbncinc > multispeed) { if (xpanelsfnbutton == 1) { cur_apcrs = cur_apcrs + multimul; } if(xpanelsfnbutton == 0) { cur_apcrs = cur_apcrs + 1; } crsdbncinc = 0; } } if(testbit(multibuf,ADJUSTMENT_DN)) { crsdbncdec++; if (crsdbncdec > multispeed) { if (xpanelsfnbutton == 1) { cur_apcrs = cur_apcrs - multimul; } if(xpanelsfnbutton == 0) { cur_apcrs = cur_apcrs - 1; } crsdbncdec = 0; } } if(cur_apcrs > 360){ cur_apcrs = 1; } if(cur_apcrs < 0){ cur_apcrs = 359; } cur_apcrsf = cur_apcrs; XPLMSetDataf(crs_dataref, cur_apcrsf); // set the appropriate global based on whether the crs toggle is on if( !xpanelscrstoggle ) { // toggle off - nav1 upapcrsf = cur_apcrsf; upapcrs = cur_apcrs; } else { // toggle on - nav2 upapcrsf2 = cur_apcrsf; upapcrs2 = cur_apcrs; upapcrs = cur_apcrs; } } }
void sendRepositionedAtAirport() { XPLMDebugString("XData: sendRepositionedAtAirport called.\n"); // where are we? float inLat; float inLon; XPLMDataRef dataref_latitude = XPLMFindDataRef("sim/flightmodel/position/latitude"); inLat = XPLMGetDataf(dataref_latitude); XPLMDataRef dataref_longitude = XPLMFindDataRef("sim/flightmodel/position/longitude"); inLon = XPLMGetDataf(dataref_longitude); XPLMNavRef navref = XPLMFindNavAid( NULL, NULL, &inLat, &inLon, NULL, xplm_Nav_Airport); float apt_lat; float apt_lon; float apt_height; char apt_id[32]; char apt_name[256]; XPLMGetNavAidInfo( navref, NULL, &apt_lat, &apt_lon, &apt_height, NULL, NULL, &apt_id, &apt_name, NULL); int i; int res; char msg[256]; sprintf(msg, "Repositioned at airport: %s (name: %s) height=%f lat=%f lon=%f\n", apt_id, apt_name, apt_height, apt_lat, apt_lon); XPLMDebugString(msg); // make endian corrections // COMMENTED OUT - THIS CRASHES X-PLANE. WHY? // apt_lat = custom_htonf(apt_lat); // apt_lon = custom_htonf(apt_lon); // apt_height = custom_htonf(apt_height); strncpy(airport_packet.apt_id, apt_id, 32); strncpy(airport_packet.apt_name, apt_name, 256); airport_packet.apt_height = apt_height; airport_packet.apt_lat = apt_lat; airport_packet.apt_lon = apt_lon; if (xdata_plugin_enabled && xdata_send_enabled && xdata_socket_open) { strncpy(airport_packet.packet_id, "RAPT", 4); for (i=0; i<NUM_DEST; i++) { if (dest_enable[i]) { res = sendto(sockfd, (const char*)&airport_packet, sizeof(airport_packet), 0, (struct sockaddr *)&dest_sockaddr[i], sizeof(struct sockaddr)); #if IBM if ( res == SOCKET_ERROR ) { XPLMDebugString("XData: caught error while sending RAPT packet! ("); sprintf(msg, "%d", WSAGetLastError()); XPLMDebugString(msg); XPLMDebugString(")\n"); } #else if ( res < 0 ) { XPLMDebugString("XData: caught error while sending RAPT packet! ("); XPLMDebugString((char * const) strerror(GET_ERRNO)); XPLMDebugString(")\n"); } #endif } } } }
float sendRequestedDataCallback( float inElapsedSinceLastCall, float inElapsedTimeSinceLastFlightLoop, int inCounter, void * inRefcon) { int i; int res; #if IBM char msg[80]; #endif struct RequestRecord rr; if( DEBUG ) { XPLMDebugString("XData: sendRequestedDataCallback called.\n"); } if (xdata_plugin_enabled && xdata_send_enabled && xdata_socket_open) { if( acf_packet_requested == 1 ) { acf_packet_requested = 0; sendAircraftPacket(); } // Tried a number of things, but absolute current time in millis just overflows and isn't printable via sprintf, it seems, as a long long. // So: initializing a start time, then evaluating time since that, which fits into an int. if( t_start.time == 0 ) { ftime(&t_start); XPLMDebugString("Initialising t_start.\n"); } struct timeb t_current; ftime(&t_current); int t_diff = (int) (1000.0 * (t_current.time - t_start.time) + (t_current.millitm - t_start.millitm)); // clear the buffer memset(response_data, 0, response_max_size); // sprintf(msg, "Time check: milliseconds since start = %d\n", t_diff); // XPLMDebugString(msg); strncpy(response_data, "REQD", 4); // first 4 bytes indicate packet type response_index = 8; number_of_points = 0; // work out which requests to send for( i=0; i<=max_requested_index; i++ ) { rr = request_records[i]; if( rr.enabled && request_records[i].dataref != NULL ) { //sprintf(msg, "%d - Checking %s which is scheduled for %d\n", t_diff, rr.dataref_name, rr.time_next_send); //XPLMDebugString(msg); if( rr.time_next_send == 0 || t_diff > rr.time_next_send ) { // let's work out the size of the data int size = 0; int nbrArrayValues = 0; int intValue = 0; float floatValue = 0.0f; double doubleValue = 0.0; int intArrayValues[20]; float floatArrayValues[20]; char data[900]; if( request_records[i].datatype == xplmType_Int ) { intValue = XPLMGetDatai(request_records[i].dataref); size = 4; } else if( request_records[i].datatype == xplmType_Float ) { floatValue = XPLMGetDataf(request_records[i].dataref); size = 4; } else if( request_records[i].datatype == xplmType_Double || request_records[i].datatype == 6 ) { // hack based on observed values doubleValue = XPLMGetDatad(request_records[i].dataref); size = 8; } else if( request_records[i].datatype == xplmType_FloatArray ) { nbrArrayValues = XPLMGetDatavf(request_records[i].dataref, floatArrayValues, 0, 20); size = (4 * nbrArrayValues); } else if( request_records[i].datatype == xplmType_IntArray ) { nbrArrayValues = XPLMGetDatavi(request_records[i].dataref, intArrayValues, 0, 20); size = (4 * nbrArrayValues); } else if( request_records[i].datatype == xplmType_Data ) { nbrArrayValues = XPLMGetDatab(request_records[i].dataref, data, 0, 900); size = nbrArrayValues; } // will it fit in the buffer int index_after_add = response_index + 4 + 4 + 4 + size; if( index_after_add >= response_max_size ) { // if not, send it // first update response with number of points int convertedNum = custom_htonl(number_of_points); memcpy(response_data+4, &convertedNum, 4); if( DEBUG ) { sprintf(msg, "Packet ready to go: number_of_points=%d response_index=%d\n", number_of_points, response_index); XPLMDebugString(msg); XPLMDebugString("Packet data: "); int p=0; for( p=0; p<response_index; p++ ) { sprintf(msg, "%d:%d ", p, (int)response_data[p]); XPLMDebugString(msg); } XPLMDebugString("\n"); } // ready to go for (i=0; i<NUM_DEST; i++) { if (dest_enable[i]) { res = sendto(sockfd, response_data, response_index, 0, (struct sockaddr *)&dest_sockaddr[i], sizeof(struct sockaddr)); #if IBM if ( res == SOCKET_ERROR ) { XPLMDebugString("XData: caught error while sending REQD packet! ("); sprintf(msg, "%d", WSAGetLastError()); XPLMDebugString(msg); XPLMDebugString(")\n"); } #else if ( res < 0 ) { XPLMDebugString("XData: caught error while sending REQD packet! ("); XPLMDebugString((char * const) strerror(GET_ERRNO)); XPLMDebugString(")\n"); } #endif } } XPLMDebugString("Sent packet\n"); response_index = 8; number_of_points = 0; } else { // otherwise add it to the buffer // TODO figure out how to either convert each of the above datatypes into char[] data, or // simply memcpy from the original dataref into the buffer. // ID|DATATYPE|LENGTH|DATA.... int convertedI = custom_htonl(i); memcpy(response_data+response_index, &convertedI, 4); response_index += 4; int convertedDatatype = custom_htonl(request_records[i].datatype); memcpy(response_data+response_index, &convertedDatatype, 4); response_index += 4; int convertedSize = custom_htonl(size); memcpy(response_data+response_index, &convertedSize, 4); response_index += 4; if( request_records[i].datatype == xplmType_Int ) { int convertedInt = custom_htonl(intValue); memcpy(response_data+response_index, &convertedInt, 4); response_index += 4; } else if( request_records[i].datatype == xplmType_Float ) { // skipping endianness conversion of float too, similar problem to double? //float convertedFloat = custom_htonf(floatValue); memcpy(response_data+response_index, &floatValue, 4); response_index += 4; if( DEBUG ) { sprintf(msg, "Converted a float: %f\n", floatValue); XPLMDebugString(msg); sprintf(msg, "%d %d %d %d\n", (int)response_data[response_index-4], (int)response_data[response_index-3], (int)response_data[response_index-2], (int)response_data[response_index-1]); XPLMDebugString(msg); } } else if( request_records[i].datatype == xplmType_Double || request_records[i].datatype == 6 ) { // hack based on observed values // Now this is weird. Converting the double breaks it somehow. Even reversing the byte order at the receiving // end doesn't work.. //double convertedDouble = custom_htond(doubleValue); memcpy(response_data+response_index, &doubleValue, 8); response_index += 8; } else if( request_records[i].datatype == xplmType_FloatArray ) { int d = 0; for( d = 0; d<nbrArrayValues; d++ ) { float convertedFloat = custom_htonf(floatArrayValues[d]); memcpy(response_data+response_index, &convertedFloat, 4); response_index += 4; } } else if( request_records[i].datatype == xplmType_IntArray ) { int d = 0; for( d = 0; d<nbrArrayValues; d++ ) { int convertedInt = custom_htonl(intArrayValues[d]); memcpy(response_data+response_index, &convertedInt, 4); response_index += 4; } } else if( request_records[i].datatype == xplmType_Data ) { memcpy(response_data+response_index, &data, size); response_index += size; } response_index = index_after_add; number_of_points++; if( DEBUG ) { sprintf(msg, "Packet accumulating: number_of_points=%d response_index=%d\n", number_of_points, response_index); XPLMDebugString(msg); } } // schedule next time request_records[i].time_next_send = t_diff + rr.every_millis; // sprintf(msg, "%d - Would send %s and rescheduled (every %d millis) for %d\n", t_diff, rr.dataref_name, rr.every_millis, rr.time_next_send); // XPLMDebugString(msg); } } } // does the buffer contain any data? if( number_of_points > 0 ) { // send it // first update response with number of points int convertedNum = custom_htonl(number_of_points); memcpy(response_data+4, &convertedNum, 4); if( DEBUG ) { sprintf(msg, "Packet ready to go: number_of_points=%d response_index=%d\n", number_of_points, response_index); XPLMDebugString(msg); XPLMDebugString("Packet data: "); int p=0; for( p=0; p<response_index; p++ ) { sprintf(msg, "%d:%d ", p, (int)response_data[p]); XPLMDebugString(msg); } XPLMDebugString("\n"); } // ready to go for (i=0; i<NUM_DEST; i++) { if (dest_enable[i]) { res = sendto(sockfd, response_data, response_index, 0, (struct sockaddr *)&dest_sockaddr[i], sizeof(struct sockaddr)); #if IBM if ( res == SOCKET_ERROR ) { XPLMDebugString("XData: caught error while sending REQD packet! ("); sprintf(msg, "%d", WSAGetLastError()); XPLMDebugString(msg); XPLMDebugString(")\n"); } #else if ( res < 0 ) { XPLMDebugString("XData: caught error while sending REQD packet! ("); XPLMDebugString((char * const) strerror(GET_ERRNO)); XPLMDebugString(")\n"); } #endif } } if( DEBUG ) { XPLMDebugString("Sent packet.\n"); } } /* long time_last_sent; long every_millis; long time_next_send; every 100 ms, create a buffer (well, reuse it for performance) and start populating it with eligible data. Keep going until the next ref would overflow the buffer. send the packet, then resume from the current ref. until there are no more eligible refs. send that last packet, if there's something in it. upon adding the data to the packet, update the struct with the calculated next send time. REQD|COUNT|ID|DATATYPE|LENGTH|DATA.....................................|(repeated ID, TYPE, LEN, DATA).. */ /* packet_size = createSituationPacket(); for (i=0; i<NUM_DEST; i++) { if (dest_enable[i]) { res = sendto(sockfd, (const char*)&sim_packet, packet_size, 0, (struct sockaddr *)&dest_sockaddr[i], sizeof(struct sockaddr)); #if IBM if ( res == SOCKET_ERROR ) { XPLMDebugString("XData: caught error while sending REQD packet! ("); sprintf(msg, "%d", WSAGetLastError()); XPLMDebugString(msg); XPLMDebugString(")\n"); } #else if ( res < 0 ) { XPLMDebugString("XData: caught error while sending REQD packet! ("); XPLMDebugString((char * const) strerror(GET_ERRNO)); XPLMDebugString(")\n"); } #endif } } */ return 0.1; } else { // print something to allow us to work out what happened. XPLMDebugString("XData: plugin enabled:"); if( xdata_plugin_enabled ) { XPLMDebugString("true\n"); } else { XPLMDebugString("false\n"); } XPLMDebugString("XData: send enabled:"); if( xdata_send_enabled ) { XPLMDebugString("true\n"); } else { XPLMDebugString("false\n"); } XPLMDebugString("XData: socket open:"); if( xdata_socket_open ) { XPLMDebugString("true\n"); } else { XPLMDebugString("false\n"); } return 0.1f; } }
int XPlaneInterface::getRadioAltitudeFt() { // this should be improved float value = XPLMGetDataf(findDataRefByCode(RADIO_ALTITUDE_CAPT)); return (int) value; }
float GetBodyRates(float elapsedMe, float elapsedSim, int counter, void * refcon) { union intbb Temp2; float phi, theta, psi; float alpha, beta; float P_flight, Q_flight, R_flight; float ax, ay, az; // Angular rates in X-Plane are specified relative to the flight path, not to the aircraft, // for reasons unknown. So that means we need to rotate by alpha and beta to get angular rates // in the aircraft body frame, which is what the UDB measures. // Retrieve rates and slip angles, and convert to radians P_flight = XPLMGetDataf(drP) / 180 * PI ; Q_flight = XPLMGetDataf(drQ) / 180 * PI ; R_flight = XPLMGetDataf(drR) / 180 * PI ; alpha = XPLMGetDataf(drAlpha) / 180 * PI; beta = XPLMGetDataf(drBeta) / 180 * PI; FLIGHTtoBCBF(P_flight, Q_flight, R_flight, alpha, beta); P_plane = P_flight; Q_plane = Q_flight; R_plane = R_flight; // Angular rate // multiply by 5632 (constant from UDB code) // Divide by SCALEGYRO(3.0 for red board) // 1 * 5632 / 3.0 = 1877.33 Temp2.BB = (int)(P_plane * 1877.33); Store2LE(&NAV_BODYRATES[6], Temp2); Temp2.BB = (int)(Q_plane * 1877.33); Store2LE(&NAV_BODYRATES[8], Temp2); Temp2.BB = (int)(R_plane * 1877.33); Store2LE(&NAV_BODYRATES[10], Temp2); // Our euler angles: // X-Plane angles are in degrees. // Phi is roll, roll to right is positive // Theta is pitch, pitch up is positive // Psi is yaw, relative to north. North is 0/360. // Convert these angles to radians first. phi =(XPLMGetDataf(drPhi)) / 180 * PI * -1.0; theta = (XPLMGetDataf(drTheta)) / 180 * PI; psi = (XPLMGetDataf(drPsi)) / 180 * PI * -1.0; // Get accelerations in OpenGL coordinate frame //ax = XPLMGetDataf(drLocal_ax); //ay = XPLMGetDataf(drLocal_ay); //az = XPLMGetDataf(drLocal_ay); ax = 0; ay = 0; az = 0; // Gravity is not included in ay, we need to add it. OGL y axis is +ve up, // so g is -9.8. ay -= (float)9.8; // Convert from OGL frame to Aircraft body fixed frame OGLtoBCBF(ax, ay, az, phi, theta, psi); ax_plane = ax; ay_plane = ay; az_plane = az; // Lastly we need to convert from X-Plane units (m/s^2) to the arbitrary units used by the UDB // Accelerations are in m/s^2 // Divide by 9.8 to get g's // Multiply by 5280 (constant from UDB code) // Divide by SCALEACCEL (2.64 for red board) // 1 / 9.8 * 5280 / 2.64 = 204.8 Temp2.BB = (int)(ax * 204.8); Store2LE(&NAV_BODYRATES[12], Temp2); Temp2.BB = (int)(ay * 204.8); Store2LE(&NAV_BODYRATES[14], Temp2); Temp2.BB = (int)(az * 204.8); Store2LE(&NAV_BODYRATES[16], Temp2); CalculateChecksum(NAV_BODYRATES); SendToComPort(sizeof(NAV_BODYRATES),NAV_BODYRATES); ReceiveFromComPort(); ServosToControls(); // float ThrottleSetting = 0; //SurfaceDeflections[CHANNEL_THROTTLE]; // float throttle[8] = {ThrottleSetting, ThrottleSetting, ThrottleSetting, ThrottleSetting, // ThrottleSetting, ThrottleSetting, ThrottleSetting, ThrottleSetting}; XPLMSetDatavf(drThro, ThrottleSettings,0,8); return -1; }
// ***************** IAS Switch Position ******************* void process_ias_switch() { if (testbit(multibuf,IAS_SWITCH)) { multiseldis = 2; upapasf = XPLMGetDataf(ApAs); upapas = (int)(upapasf); if (testbit(multibuf,ADJUSTMENT_UP)) { iasdbncinc++; if (iasdbncinc > multispeed) { n = multimul; if (xpanelsfnbutton == 1) { if (loaded737 == 1) { XPLMCommandOnce(x737mcp_spd_up_fast); } else { while (n>0) { if (XPLMGetDatai(AirspeedIsMach) == 1) { XPLMSetDataf(Airspeed, XPLMGetDataf(Airspeed) + 0.01); } else { //XPLMCommandOnce(ApAsUp); upapas = upapas + 1; } --n; } } iasdbncinc = 0; } if (xpanelsfnbutton == 0) { if (loaded737 == 1) { XPLMCommandOnce(x737mcp_spd_up); } else { if (XPLMGetDatai(AirspeedIsMach) == 1) { XPLMSetDataf(Airspeed, XPLMGetDataf(Airspeed) + 0.01); } else { //XPLMCommandOnce(ApAsUp); upapas = upapas + 1; } } iasdbncinc = 0; } } } if (testbit(multibuf,ADJUSTMENT_DN)) { iasdbncdec++; if (iasdbncdec > multispeed) { n = multimul; if (xpanelsfnbutton == 1) { if (loaded737 == 1) { XPLMCommandOnce(x737mcp_spd_down_fast); } else { while (n>0) { if (XPLMGetDatai(AirspeedIsMach) == 1) { XPLMSetDataf(Airspeed, XPLMGetDataf(Airspeed) - 0.01); } else { //XPLMCommandOnce(ApAsDn); upapas = upapas - 1; } --n; } } iasdbncdec = 0; } if (xpanelsfnbutton == 0) { if (loaded737 == 1) { XPLMCommandOnce(x737mcp_spd_down); } else { if (XPLMGetDatai(AirspeedIsMach) == 1) { XPLMSetDataf(Airspeed, XPLMGetDataf(Airspeed) - 0.01); } else { //XPLMCommandOnce(ApAsDn); upapas = upapas - 1; } } iasdbncdec = 0; } } } upapasf = upapas; XPLMSetDataf(ApAs, upapasf); upapasf = XPLMGetDataf(ApAs); if (XPLMGetDatai(AirspeedIsMach) == 1) { upapasf = (upapasf * 100); } upapas = (int)(upapasf); } }