OBJHANDLE VOBJ::prevTarget() { /*if (iTarget-1 < 0) iTarget=oapiGetVesselCount()-1; else iTarget--;*/ OBJHANDLE hVes = NULL; OBJHANDLE hTarget = oapiGetVesselByIndex(iTarget); for (int i = iTarget; i > 0; i--) { hVes = oapiGetVesselByIndex(i); if (hTarget==hVes) continue; if (VESSEL(hVes).GetPropellantCount() < 1) continue; iTarget=i; return hVes; } for (int i = oapiGetVesselCount()-1; i > iTarget; i--) { hVes = oapiGetVesselByIndex(i); if (hTarget==hVes) continue; if (VESSEL(hVes).GetPropellantCount() < 1) continue; iTarget=i; return hVes; } iTarget=0; return oapiGetVesselByIndex(iTarget); }
OBJHANDLE VOBJ::nextTarget() { /*if (iTarget+1 < oapiGetVesselCount()) iTarget++; else iTarget=0;*/ OBJHANDLE hVes=NULL; OBJHANDLE hTarget=oapiGetVesselByIndex(iTarget); for (int i = iTarget; i < oapiGetVesselCount(); i++) { hVes = oapiGetVesselByIndex(i); if (hTarget==hVes) continue; if (VESSEL(hVes).GetPropellantCount() < 1) continue; iTarget=i; return hVes; } for (int i = 0; i < iTarget; i++) { hVes = oapiGetVesselByIndex(i); if (hTarget==hVes) continue; if (VESSEL(hVes).GetPropellantCount() < 1) continue; iTarget=i; return hVes; } iTarget=0; return oapiGetVesselByIndex(iTarget); }
int VOBJ::nextTargetSource() { if (!oapiIsVessel(oapiGetVesselByIndex(iTarget))) return -1; int count = vtarget()->GetPropellantCount(); if (iTargetSource+1 < count) iTargetSource++; else iTargetSource=0; return iTargetSource; }
int VOBJ::GetIndexByHandle(OBJHANDLE h) { if (!oapiIsVessel(h)) return 0; for (int i = 0; i < oapiGetVesselCount(); i++) { if (h == oapiGetVesselByIndex(i)) return i; } return 0; }
void RMANAGER::TimeStep() { VESSEL * v = NULL; OBJHANDLE hVes = NULL; char ini[255]; for (int i = 0; i < oapiGetVesselCount(); i++) { hVes = oapiGetVesselByIndex(i); if (!oapiIsVessel(hVes)) continue; v = oapiGetVesselInterface(hVes); if (isAttended(v)) continue; if (!hasConfig(v)) continue; sprintf(ini,"./Config/orbReentryStream/%s.ini",INI(v)); atList.push_back(ReadAndAssign(ini,v)); } VOBJ * vbj = NULL; for (int i = 0; i < atList.size(); i++) { if (!atList[i]) continue; if (!oapiIsVessel(atList[i]->hook)) continue; vbj = atList[i]; v = oapiGetVesselInterface(vbj->hook); hVes = v->GetHandle(); if (calcFlux(v) > vbj->flux) { if (!vbj->th) CreateResourceAndStreams(vbj); v->SetThrusterLevel(vbj->th,1); }else if (vbj->th) v->SetThrusterLevel(vbj->th,0); } }
void DockingProbe::TimeStep(double simt, double simdt) { if (!FirstTimeStepDone) { DoFirstTimeStep(); FirstTimeStepDone = true; return; } if (UndockNextTimestep) { UpdatePort(Dockparam[1] * 0.5, simdt); OurVessel->Undock(ourPort); UndockNextTimestep = false; } if (ExtendingRetracting > 0) { if (Status >= DOCKINGPROBE_STATUS_EXTENDED) { Status = DOCKINGPROBE_STATUS_EXTENDED; ExtendingRetracting = 0; Dockproc = DOCKINGPROBE_PROC_UNDOCKED; OurVessel->Undocking(ourPort); OurVessel->SetDockingProbeMesh(); } else { Status += 0.33 * simdt; } } else if (ExtendingRetracting < 0) { if (Status <= DOCKINGPROBE_STATUS_RETRACTED) { Status = DOCKINGPROBE_STATUS_RETRACTED; ExtendingRetracting = 0; OurVessel->HaveHardDocked(ourPort); OurVessel->SetDockingProbeMesh(); } else { Status -= 0.33 * simdt; } } if (Dockproc == DOCKINGPROBE_PROC_SOFTDOCKED) { UpdatePort(Dockparam[1] * 0.5, simdt); Dockproc = DOCKINGPROBE_PROC_HARDDOCKED; } else if (Dockproc == DOCKINGPROBE_PROC_HARDDOCKED) { if (Status > DOCKINGPROBE_STATUS_RETRACTED) { UpdatePort(Dockparam[1] * 0.5 * Status / 0.9, simdt); } else { UpdatePort(_V(0,0,0), simdt); Dockproc = DOCKINGPROBE_PROC_UNDOCKED; } } // sprintf(oapiDebugString(), "Docked %d Status %.3f Dockproc %d ExtendingRetracting %d", (Docked ? 1 : 0), Status, Dockproc, ExtendingRetracting); // Switching logic if (OurVessel->DockingProbeExtdRelSwitch.IsUp() && IsPowered()) { Extend(); } else if (OurVessel->DockingProbeExtdRelSwitch.IsDown()) { if ((!OurVessel->DockingProbeRetractPrimSwitch.IsCenter() && OurVessel->DockProbeMnACircuitBraker.IsPowered() && OurVessel->PyroBusA.Voltage() > SP_MIN_DCVOLTAGE) || (!OurVessel->DockingProbeRetractSecSwitch.IsCenter() && OurVessel->DockProbeMnBCircuitBraker.IsPowered() && OurVessel->PyroBusB.Voltage() > SP_MIN_DCVOLTAGE)) { int ActiveCharges = 0; if (OurVessel->DockingProbeRetractPrimSwitch.IsUp()) ActiveCharges = ActiveCharges | DOCKINGPROBE_CHARGE_PRIM1; if (OurVessel->DockingProbeRetractPrimSwitch.IsDown()) ActiveCharges = ActiveCharges | DOCKINGPROBE_CHARGE_PRIM2; if (OurVessel->DockingProbeRetractSecSwitch.IsUp()) ActiveCharges = ActiveCharges | DOCKINGPROBE_CHARGE_SEC1; if (OurVessel->DockingProbeRetractSecSwitch.IsDown()) ActiveCharges = ActiveCharges | DOCKINGPROBE_CHARGE_SEC2; if ((ActiveCharges & RetractChargesUsed)!= ActiveCharges) Retract(); RetractChargesUsed = RetractChargesUsed | ActiveCharges; // sprintf(oapiDebugString(), "Charge Used: P1%d P2%d S1%d S2%d", RetractChargesUsed & DOCKINGPROBE_CHARGE_PRIM1 , RetractChargesUsed & DOCKINGPROBE_CHARGE_PRIM2 , RetractChargesUsed & DOCKINGPROBE_CHARGE_SEC1 , RetractChargesUsed & DOCKINGPROBE_CHARGE_SEC2); } } /// /// Begin Advanced Docking Code /// if (DockingMethod > ADVANCED){ // Code that follows is largely lifted from Atlantis... // Goal is to handle close proximity docking between a probe and drogue VECTOR3 gdrgPos, gdrgDir, gprbPos, gprbDir, gvslPos, rvel, pos, dir, rot; OurVessel->Local2Global (Dockparam[0],gprbPos); //converts probe location to global OurVessel->GlobalRot (Dockparam[1],gprbDir); //rotates probe direction to global // Search the complete vessel list for a grappling candidate. // Not very scalable ... for (DWORD i = 0; i < oapiGetVesselCount(); i++) { OBJHANDLE hV = oapiGetVesselByIndex (i); if (hV == OurVessel->GetHandle()) continue; // we don't want to grapple ourselves ... oapiGetGlobalPos (hV, &gvslPos); if (dist (gvslPos, gprbPos) < oapiGetSize (hV)) { // in range VESSEL *v = oapiGetVesselInterface (hV); DWORD nAttach = v->AttachmentCount (true); for (DWORD j = 0; j < nAttach; j++) { // now scan all attachment points of the candidate ATTACHMENTHANDLE hAtt = v->GetAttachmentHandle (true, j); const char *id = v->GetAttachmentId (hAtt); if (strncmp (id, "PADROGUE", 8)) continue; // attachment point not compatible v->GetAttachmentParams (hAtt, pos, dir, rot); v->Local2Global (pos, gdrgPos); // converts found drogue position to global v->GlobalRot (dir, gdrgDir); // rotates found drogue direction to global if (dist (gdrgPos, gprbPos) < COLLISION_DETECT_RANGE && DockingMethod == ADVANCEDPHYSICS) { // found one less than a meter away! // Detect if collision has happend, if so, t will return intersection point along the probe line X(t) = gprbPos + t * gprbDir double t = CollisionDetection(gprbPos, gprbDir, gdrgPos, gdrgDir); // Calculate time of penetration according to current velocity OurVessel->GetRelativeVel(hV, rvel); // Determine resultant force //APPLY rforce to DockingProbe Vessel, and APPLY -rforce to Drogue Vessel return; } if (dist(gdrgPos, gprbPos) < CAPTURE_DETECT_RANGE && DockingMethod > ADVANCED) { // If we're within capture range, set docking port to attachment so docking can take place // Originally, I would have used the Attachment features to soft dock and move the LM during retract // but Artlav's docking method does this better and uses the docking port itself. // Attachment is being used as a placeholder for the docking port and to identify its orientation. OurVessel->GetAttachmentParams(hattPROBE, pos, dir, rot); DOCKHANDLE dock = OurVessel->GetDockHandle(ourPort); OurVessel->SetDockParams(dock, pos, dir, rot); } }//for nAttach }//if inRange }//for nVessel } }
void VOBJ::TimeStep(int SoundID) { if (!oapiIsVessel(hook)){ sprintf(msg, "Unknown Error"); return; } if (!oapiGetVesselByIndex(iTarget) && mode == VTOV){ mode=MAGIC; iTargetSource=0; iTarget=0; } if (VESSEL(hook).GetPropellantCount() < 1) { sprintf(msg, "No fuel sources available"); return; } if (status==IDLE) { sprintf(msg, "IDLE: Waiting for action"); return; } PlayMFDWave(SoundID, 0); if (mode==VTOV) { VESSEL * vHook = oapiGetVesselInterface(hook); VESSEL * vTarget = oapiGetVesselInterface(oapiGetVesselByIndex(iTarget)); if (vTarget->GetPropellantCount() < 1) { sprintf(msg, "Target has no fuel sources"); return; } PROPELLANT_HANDLE hpTarget = vTarget->GetPropellantHandleByIndex(iTargetSource); PROPELLANT_HANDLE hpHook = vHook->GetPropellantHandleByIndex(iSelectedSource); if (!hpHook||!hpTarget){ sprintf(msg, "Unknown Error!"); return; } double maxMasstarget = vTarget->GetPropellantMaxMass(hpTarget); double massTarget = vTarget->GetPropellantMass(hpTarget); double maxMasshook = vHook->GetPropellantMaxMass(hpHook); double massHook = vHook->GetPropellantMass(hpHook); if (massTarget<CUT_OFF) { sprintf(msg, "No fuel left to transfer!"); return; } if (fabs(maxMasshook-massHook) < CUT_OFF) { sprintf(msg, "Tank full"); return; } if (hook == oapiGetVesselByIndex(iTarget)) { if (iSelectedSource == iTargetSource) { sprintf(msg, "Cannot transfer fuel to the same source"); return; } } double dFuelTrans = 0; if (massTarget-dTransferRate >= 0 && massHook+dTransferRate <= maxMasshook) { dFuelTrans = dTransferRate; }else { if (maxMasshook-massHook < massTarget) { dFuelTrans = maxMasshook-massHook; }else if (maxMasshook-massHook > massTarget) { dFuelTrans = massTarget; }else dFuelTrans = massTarget; } dFuelTrans*=oapiGetSimStep(); vTarget->SetPropellantMass(hpTarget, massTarget-dFuelTrans); vHook->SetPropellantMass(hpHook, massHook+dFuelTrans); sprintf(msg, "Transfering %.2f%%", ((massHook+dFuelTrans)/maxMasshook)*100, vTarget->GetName(), ((massTarget-dFuelTrans)/maxMasstarget)*100); } else if (mode == MAGIC) { VESSEL * v = oapiGetVesselInterface(hook); PROPELLANT_HANDLE hpr = v->GetPropellantHandleByIndex(iSelectedSource); if (!hpr) { sprintf(msg, "Unknown error!"); return; } double mass = v->GetPropellantMass(hpr); double maxmass = v->GetPropellantMaxMass(hpr); if (fabs(maxmass-mass) < CUT_OFF){ sprintf(msg, "Tank full"); return; } double dFuelTrans = 0; if (mass+dTransferRate > maxmass) dFuelTrans = maxmass-mass; else dFuelTrans = dTransferRate; dFuelTrans*=oapiGetSimStep(); v->SetPropellantMass(hpr, dFuelTrans+mass); sprintf(msg, "Transfering %.2f%%", ((mass+dFuelTrans)/maxmass)*100); }else if (mode == DUMPING) { VESSEL * v = oapiGetVesselInterface(hook); PROPELLANT_HANDLE hpr = v->GetPropellantHandleByIndex(iSelectedSource); if (!hpr) { sprintf(msg, "Unknown error!"); return; } double mass = v->GetPropellantMass(hpr); double maxmass = v->GetPropellantMaxMass(hpr); if (mass <CUT_OFF) { sprintf(msg, "No more fuel left"); return; } double dFuelTrans=0; if (mass-dTransferRate < 0) dFuelTrans = mass; else dFuelTrans = dTransferRate; dFuelTrans*=oapiGetSimStep(); v->SetPropellantMass(hpr, mass-dFuelTrans); sprintf(msg, "Dumping %.2f%%", ((mass-dFuelTrans)/maxmass)*100); } }
void EVA::clbkPreStep (double simt, double SimDT, double mjd) { char EVAName[256]=""; char CSMName[256]=""; char MSName[256]=""; strcpy(EVAName,GetName()); double VessCount; int i=0; VessCount=oapiGetVesselCount(); hMaster=oapiGetVesselByIndex(i); while (i<VessCount)i++;{ oapiGetObjectName(hMaster,MSName,256); strcpy(CSMName,MSName);strcat(CSMName,"-EVA"); if (strcmp(CSMName,EVAName)==0) { i=int(VessCount); } } sprintf(oapiDebugString(), "EVA Cable Attached to %s", MSName); VESSELSTATUS csmV; VESSELSTATUS evaV; VESSEL *csmvessel; VECTOR3 rdist = {0,0,0}; VECTOR3 posr = {0,0,0}; VECTOR3 rvel = {0,0,0}; VECTOR3 RelRot = {0,0,0}; double dist = 0.0; double Vel = 0.0; if (hMaster) { csmvessel = oapiGetVesselInterface(hMaster); oapiGetRelativePos (GetHandle() ,hMaster, &posr); oapiGetRelativeVel (GetHandle() ,hMaster , &rvel); GetStatus(evaV); csmvessel->GetStatus(csmV); GlobalRot (posr, RelRot); dist = sqrt(posr.x * posr.x + posr.y * posr.y + posr.z * posr.z); Vel = sqrt(rvel.x * rvel.x + rvel.y * rvel.y + rvel.z * rvel.z); if (dist >= 25) { rvel = evaV.rvel-csmV.rvel; rvel.x = -rvel.x; rvel.y = -rvel.y; rvel.z = -rvel.z; GetStatus(evaV); csmvessel->GetStatus(csmV); evaV.rvel = csmV.rvel + rvel; DefSetState(&evaV); } if (GoDock1){ sprintf(oapiDebugString(), "EVA Back CSM Mode Relative Distance M/s %f", dist); if (dist <= 0.55 && dist>=0.50 ){ GoDock1 =false; oapiSetFocusObject(hMaster); oapiDeleteVessel(GetHandle()); } } } }