示例#1
0
// 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);
}
示例#2
0
void RMANAGER::CreateResourceAndStreams(VOBJ * vbj)
{
	if (!oapiIsVessel(vbj->hook))
		return;
	VESSEL * vessel = oapiGetVesselInterface(vbj->hook);
	PROPELLANT_HANDLE hpr = vessel->CreatePropellantResource(1);
	vbj->th = vessel->CreateThruster(_V(0,0,0),vbj->dir,1e0,hpr,500000e50);
	for (int i = 0; i < vbj->streams.size(); i++)
	{
		vessel->AddExhaustStream(vbj->th,vbj->streams[i]->pos,vbj->streams[i]->stream);
	}
}
示例#3
0
// 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;
}
示例#4
0
// Callback from Target Selection Input Box
bool RVO_DialogFunc::clbkTGT(void *id, char *str, void *usrdata) {

  OBJHANDLE hTgtV;
  VESSEL* tv;
  bool DockFree = false;
  
  RVO_LCore* LC = (RVO_LCore*) usrdata;
  RVO_GCore* GC = LC->GC;
  RVO_VCore* VC = LC->VC;

  if (strlen(str) == 0) return true;    // Empty string - assume canceled dialog

  hTgtV = oapiGetVesselByName(str);
  if (!hTgtV) return true;               // String was not a vessel 

  tv = oapiGetVesselInterface(hTgtV);
  if (!tv) return true;               // Couldn't find the vessel interface
  if (tv == LC->v) return true;       // We can't dock with ourself (that would be rude!)

  // Target accepted 
  strcpy_s(VC->TargetText, 50, tv->GetName());
  VC->hTgtV = hTgtV;
  VC->tv = tv;

  VC->MaxPorts = VC->tv->DockCount();

  for (int i=0; i<VC->MaxPorts; i++) {

    VC->hDock = VC->tv->GetDockHandle(i);
    if (!VC->hDock) continue;                  // Couldn't find the dock??
    if (VC->tv->DockingStatus(i)==0) { // dock free
      DockFree = true;
      VC->tv->GetDockParams(VC->hDock, VC->rtvdPos, VC->rtvdDir, VC->rtvdRot);
      VC->CreatePortRotMatrix(VC->rtvPortOri,VC->rtvdDir,VC->rtvdRot);
      VC->PortNumber = i;
      break;
    }
  }

  if (!DockFree) {
    LC->showMessage = true;
    sprintf_s(LC->Message,"No free ports on %s!", VC->TargetText);
    VC->PortNumber = -1;
    VC->hDock = 0;
  }
  
  return true;

}
示例#5
0
bool RMANAGER::isAttended(VESSEL * v)
{
	if (!v)
		return false;
	VESSEL * vessel;
	for (int i = 0; i < atList.size(); i++)
	{
		if (!atList[i])
			continue;
		if (!oapiIsVessel(atList[i]->hook))
			continue;
		vessel = oapiGetVesselInterface(atList[i]->hook);
		if (v->GetHandle() == vessel->GetHandle())
			return true;
	}
	return false;
}
示例#6
0
int  VOBJ::nextlock()
{
	VESSEL * v = oapiGetVesselInterface(hook);
	UINT count = v->DockCount();
	if (dock+1 >= count)
		dock=0;
	else
		dock++;
	VECTOR3 pos, rot, dir;
	DOCKHANDLE dHandle = v->GetDockHandle(dock);
	v->GetDockParams(dHandle, pos, dir, rot);
	//crew.DefineAirLockShape(TRUE,-5,5,-5,5,-5,5);
	crew.DefineAirLockShape(TRUE, min(pos.x, -pos.x)-5, max(pos.x, -pos.x)+5, min(pos.y, -pos.y)-5, max(pos.y, -pos.y)+5, 
		min(pos.z, -pos.z)-5, max(pos.z, -pos.z)+5);
	crew.SetMembersPosRotOnEVA(pos, rot);
	crew.SetActiveDockForTransfer(dock);
	return dock;
}
示例#7
0
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);
	}
}
示例#8
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);
	}
}
示例#9
0
int VOBJ::TimeStep(void)
{
	int r = crew.ProcessUniversalMMu();
	char cbuf[255];
	switch(r)
	{
	case UMMU_RETURNED_TO_OUR_SHIP:
		{
			sprintf(cbuf,"%s %s aged %d entered the ship",crew.GetCrewMiscIdByName(crew.GetLastEnteredCrewName()),crew.GetLastEnteredCrewName(),crew.GetCrewAgeByName(crew.GetLastEnteredCrewName()));
			hudprint.insert(cbuf);
			break;
		}
	case UMMU_TRANSFERED_TO_OUR_SHIP:
		{
			sprintf(cbuf,"%s %s aged %d entered to ship",crew.GetCrewMiscIdByName(crew.GetLastEnteredCrewName()),crew.GetLastEnteredCrewName(),crew.GetCrewAgeByName(crew.GetLastEnteredCrewName()));
			hudprint.insert(cbuf);
			break;
		}
	}
	if (!koc || !crew.GetCrewTotalNumber())
		return r;
	VESSEL * v = oapiGetVesselInterface(hook);
	VECTOR3 horz;
	v->GetHorizonAirspeedVector(horz);
	if (horz.y < khv && v->GroundContact())
	{
		for (int i = 0; i < crew.GetCrewTotalNumber(); i++)
		{
			crew.SetCrewMemberPulseByName(crew.GetCrewNameBySlotNumber(i),0);
		}
		while(crew.GetCrewTotalNumber())
			crew.EjectCrewMember(crew.GetCrewNameBySlotNumber(0));
		sprintf(cbuf,"crash at %.2f everybody dead",horz.y);
		hudprint.insert(cbuf);
	}
	return r;
}
示例#10
0
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();
}
示例#11
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
	}
}
示例#12
0
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);	

}
示例#13
0
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);
	}
}
示例#14
0
文件: eva.cpp 项目: dseagrav/NASSP
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());
			}
		}

	}
}
示例#15
0
// 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;
}
示例#16
0
const MATRIX3 &AttitudeReference::GetFrameRotMatrix () const
{
	// Returns rotation matrix for rotation from reference frame to global frame

	if (!valid_axes) {
		VECTOR3 axis1, axis2, axis3;
		switch (mode) {
		case 0:    // inertial (ecliptic)
			axis3 = _V(1,0,0);
			axis2 = _V(0,1,0);
			break;
		case 1: {  // inertial (equator)
			MATRIX3 R;
			oapiGetPlanetObliquityMatrix (v->GetGravityRef(), &R);
			//axis3 = _V(R.m13, R.m23, R.m33);
			axis3 = _V(R.m11, R.m21, R.m31);
			axis2 = _V(R.m12, R.m22, R.m32);
			} break;
		case 2: {  // orbital velocity / orbital momentum vector
			OBJHANDLE hRef = v->GetGravityRef();
			v->GetRelativeVel (hRef, axis3);
			axis3 = unit (axis3);
			VECTOR3 vv, vm;
			v->GetRelativePos (hRef, vv);    // local vertical
			vm = crossp (axis3,vv);    // direction of orbital momentum
			axis2 = unit (crossp (vm,axis3));
			} break;
		case 3: {  // local horizon / local north (surface)
			OBJHANDLE hRef = v->GetSurfaceRef();
			v->GetRelativePos (hRef, axis2);
			axis2 = unit (axis2);
			MATRIX3 prot;
			oapiGetRotationMatrix (hRef, &prot);
			VECTOR3 paxis = {prot.m12, prot.m22, prot.m32};  // planet rotation axis in global frame
			VECTOR3 yaxis = unit (crossp (paxis,axis2));      // direction of yaw=+90 pole in global frame
			axis3 = crossp (axis2,yaxis);
			} break;
		case 4: {  // synced to NAV source (type-specific)
			NAVDATA ndata;
			NAVHANDLE hNav = v->GetNavSource (navid);
			axis3 = _V(0,0,1);
			axis2 = _V(0,1,0);
			if (hNav) {
				oapiGetNavData (hNav, &ndata);
				switch (ndata.type) {
				case TRANSMITTER_IDS: {
					VECTOR3 pos, dir, rot;
					MATRIX3 R;
					VESSEL *vtgt = oapiGetVesselInterface (ndata.ids.hVessel);
					vtgt->GetRotationMatrix (R);
					vtgt->GetDockParams (ndata.ids.hDock, pos, dir, rot);
					axis3 = -mul(R,dir);
					axis2 = mul(R,rot);
					} break;
				case TRANSMITTER_VTOL:
				case TRANSMITTER_VOR: {
					OBJHANDLE hRef = v->GetSurfaceRef();
					VECTOR3 spos, npos;
					v->GetRelativePos (hRef, axis2);
					v->GetGlobalPos (spos);
					axis2 = unit (axis2);
					oapiGetNavPos (hNav, &npos);
					npos -= spos;
					axis3 = unit(crossp(crossp(axis2,npos),axis2));
					} break;
				}
			}
			} break;
		}
		axis1 = crossp(axis2,axis3);
		R = _M(axis1.x, axis2.x, axis3.x,  axis1.y, axis2.y, axis3.y,  axis1.z, axis2.z, axis3.z);

		valid_axes = true;
		valid_euler = false;
	}
	return R;
}