void RadioPanel::updateDisplay() { static unsigned char buf[23]; if (!handle) { return; } VESSEL *vessel = oapiGetFocusInterface(); // Get current vessel if (vessel!=NULL) // check if pointer is valid { buf[0]=0x00; // parse nav1 parseNavData(vessel, 0, &(buf[1])); // parse nav2 parseNavData(vessel, 1, &(buf[11])); int res = hid_send_feature_report(handle, buf, 23); } }
void FuelMFD::Update (HDC hDC) { int maxtanks; char Buffer[100]; v = oapiGetFocusInterface(); maxtanks=v->GetPropellantCount(); maxpage = maxtanks/6; // max 6 tanks per page if (maxtanks%6==0) maxpage--; SetTextColor(hDC, RGB(0, 255, 0)); // Display Color: Green Title (hDC, "Fuel Reserve Display"); sprintf_s(Buffer,"%i/%i",page+1,maxpage+1); TextOut(hDC, 250, 0, Buffer, strlen(Buffer)); CurrentLine = 2*LINE; //Beginning of the display for (int i=1; (i<=6) && (i+page*6<=maxtanks) ; i++) { FuelBar(hDC, i+page*6 , CurrentLine); CurrentLine += LINE*4; } }
// Basically NAVMODE_KILLROT in a single dimension. Returns true when the rate has been nulled // out, otherwise it returns false. bool NullRate(AXIS Axis) { VESSEL *Vessel = oapiGetFocusInterface(); VESSELSTATUS Status; Vessel->GetStatus(Status); double RateDeadband = Radians(0.001), Thrust, Level, Rate = Status.vrot.data[Axis], Mass = Vessel->GetMass(), MaxThrust = Vessel->GetMaxThrust(ENGINE_ATTITUDE), Size = Vessel->GetSize(); VECTOR3 PMI; Vessel->GetPMI(PMI); if (fabs(Rate) < RATE_NULL) { Vessel->SetAttitudeRotLevel(Axis, 0.0); return true; } Thrust = -(Mass * PMI.data[Axis] * Rate) / (Size); Level = min((Thrust/MaxThrust), 1); Vessel->SetAttitudeRotLevel(Axis, Level); return false; }
bool EHUD::isFocus(OBJHANDLE h) { if (!oapiIsVessel(h)) return false; if (oapiGetFocusInterface()->GetHandle() == h) return true; return false; }
// Wrapper for the above function that assumes that the rotation rate is vrot. // Calling the function directly allows more control but will probably be used less bool SetAttitude(double TargetAttitude, double CurrentAttitude, AXIS Axis, DEADBAND DeadbandLow) { VESSEL *Vessel; // Spacecraft interface VESSELSTATUS Status; // Spacecraft status Vessel = oapiGetFocusInterface(); Vessel->GetStatus(Status); return SetAttitude(TargetAttitude, CurrentAttitude, Status.vrot.data[Axis], Axis, DeadbandLow); }
DLLCLBK void opcPreStep(double simt, double simdt, double mjd) { OrbiterPluginMessage * opm; // holds our msg and msg data char * msg; int len; // nextMessage() returns MESSAGE_OK if a message is succesfully polled while(OICOM::nextMessage(pid, &opm)==MESSAGE_OK) { msg=opm->strMsg; len=strlen(msg); // we don't care about any text only events for this module if ( opm->data == 0 ) { // remove this message from the message stack OICOM::removeLastMessage(pid); continue; } // perma-link! hook up this module's state variables with any module providing input // this is powerful if ( !_strnicmp(msg, "link_state", len) ) active=(bool*)opm->data; else if (!_strnicmp(msg, "link_setpoint", len) ) setpoint=(double*)opm->data; OICOM::removeLastMessage(pid); // this is important otherwise we'll end up with an infinite loop! // I am thinking about automating it.. calling this at nextMessage } // if not linked to any module for input, no need to proceed if ( active == 0 || setpoint == 0 ) return; if ( !*active ) return; // crappy "autopilot" code follows, IGNORE IT xD VESSEL * vessel = oapiGetFocusInterface(); DWORD inx = vessel->GetGroupThrusterCount(THGROUP_MAIN); VECTOR3 dv; vessel->GetDragVector(dv); THRUSTER_HANDLE th; double e = *setpoint-vessel->GetAirspeed(); double lvl = 0; for (DWORD i = 0; i < inx; i++) { th = vessel->GetGroupThruster(THGROUP_MAIN, i); lvl = (-dv.z+e*vessel->GetMass()*70)/vessel->GetThrusterMax0(th); if (lvl<0) lvl=0; else if (lvl>1) lvl=1; vessel->SetThrusterLevel(th, lvl); } }
void SwitchPanel::checkInputs() { static unsigned char inBuffer[5]; if (!handle) { return; } VESSEL *vessel = oapiGetFocusInterface(); // Get current vessel int bytesRead = hid_read(handle, inBuffer, sizeof(inBuffer)); if (vessel!=NULL) // check if pointer is valid { //0x04 >> gear up //0x08 >> gear down if (bytesRead==3) { char keyByte = inBuffer[2]; if (keyByte & 0x04) { // gear up setGear(vessel, true); } if (keyByte & 0x08) { // gear down setGear(vessel, false); } } } }
bool RMANAGER::isFocus(VESSEL * v) { if (v->GetHandle() == oapiGetFocusInterface()->GetHandle()) return true; return false; }
DLLCLBK void opcPreStep(double simt, double simdt, double mjd) { if (Init==FALSE) { if (ConfigLoaded==FALSE) g_UFA.init(); LoadOptions(); Init=TRUE; srand(time(NULL)); return; } g_UFA.TimeStep(); HUD.TimeStep(); VOBJ * v = g_UFA.GetFocus(); if (v==NULL) return; char cbuf[255]; if (Ejection==TRUE) { if (lEjectionTime>oapiGetSimTime()) return; lEjectionTime=oapiGetSimTime()+1; int crewcount = v->crew.GetCrewTotalNumber(); if (!crewcount){ Ejection=FALSE; return; } double eVel = 0; VESSEL * vessel = NULL; VESSEL * focus = oapiGetFocusInterface(); VESSELSTATUS vs; OBJHANDLE hVes=NULL; if (VESSEL(v->hook).GetAtmPressure() < 2.5) { eVel=5; v->crew.SetEjectPosRotRelSpeed(_V(0, 0, 0),_V(0,1,0), _V(eVel,eVel, 0)); v->crew.EjectCrewMember(v->crew.GetCrewNameBySlotNumber(0)); }else { v->crew.SetEjectPosRotRelSpeed(_V(0, 0, 0),_V(0,1,0), _V(0,0, 0)); v->crew.EjectCrewMember(v->crew.GetCrewNameBySlotNumber(0)); } hVes = v->crew.GetObjHandleOfLastEVACrew(); if (!oapiIsVessel(hVes)) return; vessel = oapiGetVesselInterface(hVes); sprintf(cbuf,"%s-pack",vessel->GetName()); vessel->GetStatus(vs); oapiCreateVessel(cbuf,"Ummuturbopack",vs); } double yofs = Y_OFS_START; for (int i = 0; i < v->hudprint.m.size(); i++) { sprintf(cbuf,"%s",v->hudprint.m[i].c_str()); HUD.Add(0.0001,v->hook,HUD._D(X_OFS_START,1,yofs,1,Size,COLOR,cbuf)); yofs+=LINE_SPACE; } HUD.TimeStep(); }
void RadioPanel::checkInputs() { static unsigned char inBuffer[5]; if (!handle) { return; } VESSEL *vessel = oapiGetFocusInterface(); // Get current vessel if (vessel!=NULL) // check if pointer is valid { //0x01 >> 1 i u //0x02 >> 1 i d //0x04 >> 1 o u //0x08 >> 1 o d //0x10 >> 2 i u //0x20 >> 2 i d //0x40 >> 2 o u //0x80 >> 2 o d int bytesRead = hid_read(handle, inBuffer, sizeof(inBuffer)); if (bytesRead==3) { char keyByte = inBuffer[2]; if (keyByte & 0x01) { increaseNav(vessel,0,true,true); } if (keyByte & 0x02) { increaseNav(vessel,0,true,false); } if (keyByte & 0x04) { increaseNav(vessel,0,false,true); } if (keyByte & 0x08) { increaseNav(vessel,0,false,false); } if (keyByte & 0x10) { increaseNav(vessel,1,true,true); } if (keyByte & 0x20) { increaseNav(vessel,1,true,false); } if (keyByte & 0x40) { increaseNav(vessel,1,false,true); } if (keyByte & 0x80) { increaseNav(vessel,1,false,false); } } } }
void SwitchPanel::updateDisplay() { // 0x00 off // 0x07 green // 0x38 red static unsigned char buf[2]; if (!handle) { return; } buf[0]=0x00; buf[1]=0x00; VESSEL *vessel = oapiGetFocusInterface(); // Get current vessel if (vessel!=NULL) // check if pointer is valid { if (XRVesselCtrl::IsXRVesselCtrl(vessel)) { // is XR vessel XRVesselCtrl * xrVessel = static_cast<XRVesselCtrl *>(vessel); if (xrVessel->GetCtrlAPIVersion() >= THIS_XRVESSELCTRL_API_VERSION) { XRDoorState doorState = xrVessel->GetDoorState(XRD_Gear,NULL); switch (doorState) { case XRDS_Open: // green buf[1]=0x07; break; case XRDS_Opening: case XRDS_Closing: // red buf[1]=0x38; break; default: // off buf[1]=0x00; break; } } } else if(strcmp(vessel->GetClassNameA(),"DeltaGlider")==0 || strcmp(vessel->GetClassNameA(),"DG-S")==0) { DeltaGlider * dgVessel = static_cast<DeltaGlider *>(vessel); switch (dgVessel->gear_status) { case DeltaGlider::DOOR_OPEN: // green buf[1]=0x07; break; case DeltaGlider::DOOR_OPENING: case DeltaGlider::DOOR_CLOSING: // red buf[1]=0x38; break; default: // off buf[1]=0x00; break; } } } int res = hid_send_feature_report(handle, buf, 2); }
// Generates rotational commands in order to achieve a target attitude in a given axis. // Note that the user is responsible for providing an accurate current attitude information. // This allows for greater flexability but also can be a source of problems if you pass // incorrect data to the function. For example, if you invert signs, then the spacecraft will // fly out of control because as it rotates in the correct direction, the DeltaAngle will // increase! Please be careful :-) The function returns true when the desired attitude // has been reached (within the given deadband) and the velocity has been nulled; otherwise, // it returns false. bool SetAttitude(double TargetAttitude, double CurrentAttitude, double RotRate, AXIS Axis, DEADBAND DeadbandLow) { VESSEL *Vessel; // Spacecraft interface double Rate; // Depends on magnitude of DeltaAngle double RateDeadband; // Depends on the magnitude of Rate double Thrust; // Thrust required double Level; // Required thrust level [0 - 1] VECTOR3 PMI; // Prinicple moment of inertia double MaxThrust; // Maximum thrust delivered by the engines double Size; // Spacecraft radius double Mass; // Spacecraft mass double DeltaRate; // The difference between the desired and the actual rate double DeltaAngle = TargetAttitude - CurrentAttitude; // Get State Vessel = oapiGetFocusInterface(); Vessel->GetPMI(PMI); MaxThrust = Vessel->GetMaxThrust(ENGINE_ATTITUDE); Mass = Vessel->GetMass(); Size = Vessel->GetSize(); // Let's take care of the good case first :-) if ((fabs(DeltaAngle) < DeadbandLow)) { //sprintf(oapiDebugString(), "NULL"); if (fabs(RotRate) < RATE_NULL) { Vessel->SetAttitudeRotLevel(Axis, 0); return true; } return (NullRate(Axis)); } // CCK // Now, we actually have to DO something! ;-) Well divide it up into two cases, once // for each direction. There's probably a better way, but not right now :-) //if (fabs(DeltaAngle) < DEADBAND_MID) { // Rate = RATE_LOW; // sprintf(oapiDebugString(), "LOW"); //} else if(fabs(DeltaAngle) < DEADBAND_HIGH) { // Rate = RATE_MID; // sprintf(oapiDebugString(), "MID"); //} else { // Rate = RATE_HIGH; // sprintf(oapiDebugString(), "HIGH"); //} if (fabs(DeltaAngle) < DEADBAND_LOW) { Rate = RATE_FINE; //sprintf(oapiDebugString(), "FINE"); } else if (fabs(DeltaAngle) < DEADBAND_MID) { Rate = RATE_LOW; //sprintf(oapiDebugString(), "LOW"); } else if (fabs(DeltaAngle) < DEADBAND_HIGH) { Rate = RATE_MID; //sprintf(oapiDebugString(), "MID"); } else if (fabs(DeltaAngle) < DEADBAND_MAX) { Rate = RATE_HIGH; //sprintf(oapiDebugString(), "HIGH"); } else { Rate = RATE_MAX; //sprintf(oapiDebugString(), "MAX"); } // CCK End RateDeadband = min(Rate / 2, Radians(0.01/*2*/)); if (DeltaAngle < 0 ) { Rate = -Rate; RateDeadband = -RateDeadband; } DeltaRate = Rate - RotRate; if (DeltaAngle > 0) { if (DeltaRate > RateDeadband) { Thrust = (Mass * PMI.data[Axis] * DeltaRate) / (Size); Level = min((Thrust/MaxThrust), 1); Vessel->SetAttitudeRotLevel(Axis, Level); } else if (DeltaRate < -RateDeadband) { Thrust = (Mass * PMI.data[Axis] * DeltaRate) / (Size); Level = max((Thrust/MaxThrust), -1); Vessel->SetAttitudeRotLevel(Axis, Level); } else { Vessel->SetAttitudeRotLevel(Axis, 0); } } else { if (DeltaRate < RateDeadband) { Thrust = (Mass * PMI.data[Axis] * DeltaRate) / (Size); Level = max((Thrust/MaxThrust), -1); Vessel->SetAttitudeRotLevel(Axis, Level); } else if (DeltaRate > -RateDeadband) { Thrust = (Mass * PMI.data[Axis] * DeltaRate) / (Size); Level = min((Thrust/MaxThrust), 1); Vessel->SetAttitudeRotLevel(Axis, Level); } else { Vessel->SetAttitudeRotLevel(Axis, 0); } } return false; }