예제 #1
0
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);	
	}

}
예제 #2
0
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;
	}
}
예제 #3
0
파일: Control.cpp 프로젝트: dseagrav/NASSP
// 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
bool EHUD::isFocus(OBJHANDLE h)
{
	if (!oapiIsVessel(h))
		return false;
	if (oapiGetFocusInterface()->GetHandle() == h)
		return true;
	return false;
}
예제 #5
0
파일: Control.cpp 프로젝트: dseagrav/NASSP
// 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);
}
예제 #6
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);
	}
}
예제 #7
0
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);
			}


		}
	}


}
예제 #8
0
bool RMANAGER::isFocus(VESSEL * v)
{
	if (v->GetHandle() == oapiGetFocusInterface()->GetHandle())
		return true;
	return false;
}
예제 #9
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();
}
예제 #10
0
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);
			}
		}
	}


}
예제 #11
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);	

}
예제 #12
0
파일: Control.cpp 프로젝트: dseagrav/NASSP
// 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;
}