SDK Question Altitude in VS2

martins

Orbiter Founder
Orbiter Founder
Joined
Mar 31, 2008
Messages
2,448
Reaction score
462
Points
83
Website
orbit.medphys.ucl.ac.uk
The hover subsystem class controls the DG's hover engines. Both responding to manual input and implementing the attitude control and the hold alt/vspd autopilots. The specific method I pointed out is the feedback loop that controls the attitude by modulating the thrust differences between the three hover engines.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,636
Reaction score
2,613
Points
203
Location
Dallas, TX
Thanks
This is what I was asking about:
Code:
// ==============================================================
//                ORBITER MODULE: DeltaGlider
//                  Part of the ORBITER SDK
//          Copyright (C) 2001-2016 Martin Schweiger
//                   All rights reserved
//
// DGSubsys.h
// Base classes for DG subsystems and panel elements
// ==============================================================

#ifndef __DGSUBSYS_H
#define __DGSUBSYS_H

#include "DRAGONFLYTITAN.h"
//#include "..\Common\Vessel\Instrument.h"

// ==============================================================

class DGSubsystem: public Subsystem {
public:
	DGSubsystem(DRAGONFLYTITAN *v) : Subsystem(v) {}
	DGSubsystem (DGSubsystem *subsys): Subsystem (subsys) {}
	inline DRAGONFLYTITAN *DF() { return (DRAGONFLYTITAN*)Vessel(); }
	inline const DRAGONFLYTITAN *DF() const { return (DRAGONFLYTITAN*)Vessel(); }
};


protected:
	DRAGONFLYTITAN *df;
};

#endif // !__DGSUBSYS_H

I wonder if I can just remove that stuff and keep the hover balance stuff?

So for now 4 hover thrusters

Not sure on this part how to add the 4th thruster:
Code:
void HoverAttitudeComponent::TrackHoverAtt ()
{
	if (mode) {
		phover = DF()->GetPitch();
		rhover = DF()->GetBank();
		const double fb_scale = 3.0/4.55; // scaling between front and back hovers (distance from CG)
		double Lf = HoverSubsys()->GetThrusterLevel(0);
		double Ll = HoverSubsys()->GetThrusterLevel(1);
		double Lr = HoverSubsys()->GetThrusterLevel(2);
		double LF = HoverSubsys()->GetThrusterLevel(3);
		double Lb = (Ll+Lr)*0.5;
		double Lm = (Lf+Lb)*0.5;
		double Tf = Lf;
		double Tb = Lb*fb_scale;
		double Tm = (Tf+Tb)*0.5;
		if (fabs(phover) <= MAX_AUTO_HOVER_ATT && fabs(rhover) <= MAX_AUTO_HOVER_ATT) { // within control range
			const double p_alpha = 0.2;
			const double p_beta = 0.6;
			const double r_alpha = 0.2;
			const double r_beta = 0.6;
			double dp = phover - phover_cmd;
			double dr = rhover - rhover_cmd;
			VECTOR3 avel;
			DF()->GetAngularVel(avel);
			double dpv =  avel.x;
			double drv = -avel.z;
			double balance_fb = -p_alpha*dp - p_beta*dpv;
			double balance_lr = -r_alpha*dr - r_beta*drv;
			if (Lf || Lb) {
				// front/back balance
				double Lf_cmd = Lm+balance_fb;
				double Lb_cmd = Lm-balance_fb;
				double D = (Lf_cmd-Lf + (Lb_cmd-Lb)*fb_scale)/(1.0+fb_scale);
				Lf_cmd -= D;
				Lb_cmd -= D;

				double Lmin = min (Lf_cmd, Lb_cmd);
				double Lmax = max (Lf_cmd, Lb_cmd);
				if (Lmin < 0.0) {
					if (Lf_cmd < 0.0) Lf_cmd = 0.0, Lb_cmd += Lmin/fb_scale;
					else              Lb_cmd = 0.0, Lf_cmd += Lmin*fb_scale;
				}
				if (Lmax > 1.0) {
					if (Lf_cmd > 1.0) Lf_cmd = 1.0, Lb_cmd += (Lmax-1.0)/fb_scale;
					else              Lb_cmd = 1.0, Lf_cmd += (Lmax-1.0)*fb_scale;
				}
				// left/right balance
				double Ll_cmd = Lb_cmd-balance_lr;
				double Lr_cmd = Lb_cmd+balance_lr;
				Lmin = min (Ll_cmd, Lr_cmd);
				Lmax = max (Ll_cmd, Lr_cmd);
				if (Lmin < 0.0) {
					if (Ll_cmd < 0.0) Ll_cmd = 0.0, Lr_cmd += Lmin;
					else              Lr_cmd = 0.0, Ll_cmd += Lmin;
				}
				if (Lmax > 1.0) {
					if (Ll_cmd > 1.0) Ll_cmd = 1.0, Lr_cmd += Lmax-1.0;
					else              Lr_cmd = 1.0, Ll_cmd += Lmax-1.0;
				}
				HoverSubsys()->SetThrusterLevel (0, Lf_cmd);
				HoverSubsys()->SetThrusterLevel (1, Ll_cmd);
				HoverSubsys()->SetThrusterLevel (2, Lr_cmd);
			}
		} else {
			double L_cmd = 2.0*Tm / (1.0 + fb_scale);
			for (int i = 0; i < 3; i++)
				HoverSubsys()->SetThrusterLevel (i, L_cmd);
		}
	} else {
		phover = rhover = phover_cmd = rhover_cmd = 0.0;
	}
	
}
 

martins

Orbiter Founder
Orbiter Founder
Joined
Mar 31, 2008
Messages
2,448
Reaction score
462
Points
83
Website
orbit.medphys.ucl.ac.uk
The DG controls pitch attitude by modulating the thrust difference between the front hover thruster and the two back hover thrusters. It controls bank attitude by modulating the thrust difference between the left and right back hover thrusters.

Your drone would control pitch attitude by modulating the thrust difference between the two front and the two back rotors. It controls the bank attitude by modulating the thrust difference between the two left and the two right rotors.

There is an additional constraint by keeping the total thrust constant (or controlled by the additional input from a hold altitude or hold vspeed autopilot) The combination of this and the attitude control should give you the target thrusts for each of the 4 rotors. This then has to be fed into the feedback loop. The DG code uses the usual damped harmonic oscillator model for this. We discussed harmonic oscillators at length for the gear suspension - I hope you remember, or otherwise look it up again.

Please note that all the constants in the DG code (in particular the stiffness and damping parameters of the oscillator) are adjusted to the DG's inertia characteristics. You can't copy those, but instead need to find the appropriate values for your drone, either by calculating the aperiodic limit, or by trial and error.

Once the low-level controls (set a target attitude, set a target altitude or vspeed) are implemented, you can start on the higher level modes. For example, if the operator commands a forward motion, the drone would have to

- pitch down to convert part of its thrust into a horizontal component
- increase the total thrust to keep the vertical component constant

The pitch-down control would itself be part of a feedback control loop to keep to the commanded horizontal velocity.

Or if you want the drone to keep hovering over a given point in the presence of (changing) wind velocities, you would have to use pitch and bank attitude to create the required horizontal velocity component to compensate.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,636
Reaction score
2,613
Points
203
Location
Dallas, TX
Thanks. Yes that part makes sense.

"(set a target attitude, set a target altitude or vspeed) " that is the horizontal hold, right?

But what to do about the subsystem?
Code:
class DGSubsystem: public Subsystem

Away from compiling pc so I can't post the error.
 

martins

Orbiter Founder
Orbiter Founder
Joined
Mar 31, 2008
Messages
2,448
Reaction score
462
Points
83
Website
orbit.medphys.ucl.ac.uk
But what to do about the subsystem?
Code:
class DGSubsystem: public Subsystem
The DG is derived from the ComponentVessel class which introduces the concept of subsystems to allow modularizing the different subsystems of the vessel. You can either use that mechanism or not, as you prefer.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,636
Reaction score
2,613
Points
203
Location
Dallas, TX
OK. I may just remove that and go from there. THe first test after compiling will if I get thrusters to fire up. Hopefully the craft will rise up level.

---------- Post added 08-02-19 at 07:31 AM ---------- Previous post was 08-01-19 at 09:36 AM ----------

So I am starting a new solution

Added hover engines but get a CTD when I apply them;
Code:
ph_main = CreatePropellantResource(FUELMASS);

	th_hover[0] = CreateThruster(_V(5, 0, 5), _V(0, 1, 0), 10 / 4, ph_main, RCS_ISP);
	th_hover[1] = CreateThruster(_V(-5, 0, 5), _V(0, 1, 0), 10 / 4, ph_main, RCS_ISP);
	th_hover[2] = CreateThruster(_V(5, 0, -5), _V(0, 1, 0), 10 / 4, ph_main, RCS_ISP);
	th_hover[3] = CreateThruster(_V(-5, 0, -5), _V(0, 1, 0), 10 / 4, ph_main, RCS_ISP);

	AddExhaust(th_hover[0], 1, 0.3, _V(0, -2.8, 0), _V(0, -1, 0));
	thg_hover = CreateThrusterGroup(th_hover, 4, THGROUP_HOVER);

h.
Code:
	//NEW
	PROPELLANT_HANDLE ph_main;
	THRUSTER_HANDLE th_hover[4];
	THRUSTER_HANDLE  thg_hover;
Code:
const double MAXSPEED = 10; /* (2.78m/s = 10km/h) */
const double MASS = 450;
const double FUELMASS = 10;
const double RCS_ISP = 2900;


---------- Post added at 09:15 AM ---------- Previous post was at 07:31 AM ----------

So here is the cpp and h Not sure why CTD when hover is applied?
Code:
// ==============================================================

//                  Part of the ORBITER SDK
//          Copyright (C) 2002-2004 Martin Schweiger
//                   All rights reserved
//


// ==============================================================
#define STRICT
#define ORBITER_MODULE

#include "orbitersdk.h"
#include "DRAGONFLYTITAN.h"
#include <math.h>
#include <stdio.h>

#include <vector>

VISHANDLE MainExternalMeshVisual = 0;





DRAGONFLYTITAN::DRAGONFLYTITAN(OBJHANDLE hObj, int fmodel) : VESSEL3(hObj, fmodel) {

	DefineAnimations();
	Height_From_Ground = 0;

	
}

void DRAGONFLYTITAN::clbkPreStep(double simt, double simdt, double mjd) {

	
	

}
void DRAGONFLYTITAN::clbkSetClassCaps(FILEHANDLE cfg) {
	// physical specs
	SetSize(6.08);
	SetEmptyMass(MASS);
	SetCW(0.9, 0.9, 2, 1.4);
	SetWingAspect(0.1);
	SetWingEffectiveness(0.1);
	SetCrossSections(_V(232.84, 1220.32, 166.36));
	SetRotDrag(_V(0.1, 0.1, 0.1));
	if (GetFlightModel() >= 1) {
		SetPitchMomentScale(1e-4);
		SetBankMomentScale(1e-4);
	}
	SetPMI(_V(163.54, 208.04, 76.03));
	SetTrimScale(0.05);
	SetCameraOffset(_V(0, 1, 3.121));

	double ro = Passo;
	TOUCHDOWNVTX td[4];

	double x_target = -0.5;
	double stiffness = (-1)*(MASS*9.80655) / (3 * x_target);
	double damping = 0.9*(2 * sqrt(MASS*stiffness));
	for (int i = 0; i<4; i++)
	{

		td[i].damping = damping;
		td[i].mu = 3;
		td[i].mu_lng = 3;
		td[i].stiffness = stiffness;
	}
	td[0].pos.x = cos(30 * RAD)*ro;
	td[0].pos.y = -Height_From_Ground;
	td[0].pos.z = -sin(30 * RAD)*ro;
	td[1].pos.x = 0;
	td[1].pos.y = -Height_From_Ground;
	td[1].pos.z = 1 * ro;
	td[2].pos.x = -cos(30 * RAD)*ro;
	td[2].pos.y = -Height_From_Ground;
	td[2].pos.z = -sin(30 * RAD)*ro;
	td[3].pos.x = 0;
	td[3].pos.y = 15 * ro;
	td[3].pos.z = 0;


	SetTouchdownPoints(td, 4);
	
	SetMeshVisibilityMode(AddMesh(oapiLoadMeshGlobal("DRAGONFLYTITAN1")), MESHVIS_ALWAYS); //Main ship mesh
	

	ph_main = CreatePropellantResource(FUELMASS);

	th_hover[0] = CreateThruster(_V(5, 0, 5), _V(0, 1, 0), 10 / 4, ph_main, RCS_ISP);
	th_hover[1] = CreateThruster(_V(-5, 0, 5), _V(0, 1, 0), 10 / 4, ph_main, RCS_ISP);
	th_hover[2] = CreateThruster(_V(5, 0, -5), _V(0, 1, 0), 10 / 4, ph_main, RCS_ISP);
	th_hover[3] = CreateThruster(_V(-5, 0, -5), _V(0, 1, 0), 10 / 4, ph_main, RCS_ISP);


	thg_hover = CreateThrusterGroup(th_hover, 4, THGROUP_HOVER);




}




void DRAGONFLYTITAN::clbkPostStep(double simt, double simdt, double mjd) {
	
}

DLLCLBK VESSEL *ovcInit(OBJHANDLE hvessel, int flightmodel) {
	return new DRAGONFLYTITAN(hvessel, flightmodel);
}

DLLCLBK void ovcExit(VESSEL *vessel) {
	if (vessel) delete (DRAGONFLYTITAN*)vessel;
}

// --------------------------------------------------------------
// Keyboard interface handDRAGONFLYTITAN (buffered key events)
// --------------------------------------------------------------
int DRAGONFLYTITAN::clbkConsumeBufferedKey(DWORD key, bool down, char *kstate) {
	// only process keydown events
	if (!down) return 0;
	return 0;
}


void DRAGONFLYTITAN::DefineAnimations(void) {
	
}


void DRAGONFLYTITAN::clbkVisualCreated(VISHANDLE vis, int refcount) {
	MainExternalMeshVisual = GetMesh(vis, 0);
	// We warn the user, in the case UMmu isn't installed it's a good idea to send a "oapiDebugString"
	// Orbiter message, otherwise your addon will not be fully operational and user may not notice. 
	// (nobody read doc, you may be the only one, if you read this send me a postcard ;)

}

// ============================================================== 
// Visual destroyed
// ============================================================== 
void DRAGONFLYTITAN::clbkVisualDestroyed(VISHANDLE vis, int refcount) {
	MainExternalMeshVisual = 0;
}


// ======================================================================== 
// clbkLoadState function of Orbiter - Save scenario when user exit Orbiter 
// ======================================================================== 
void DRAGONFLYTITAN::clbkSaveState(FILEHANDLE scn) {
	char cbuf[256];
	

	VESSEL2::clbkSaveState(scn);
	
}

// ======================================================================== 
// clbkLoadStateEx function of Orbiter - Load Orbiter scenario 
// ======================================================================== 
void DRAGONFLYTITAN::clbkLoadStateEx(FILEHANDLE scn, void *status) {
	float wheelrot = 0.0;
	char *line;
	while (oapiReadScenario_nextline(scn, line)) {

		
		{
			ParseScenarioLineEx(line, status);
			// unrecognised option - pass to Orbiter's generic parser
		}
		
		
	}

}


void DRAGONFLYTITAN::clbkFocusChanged(bool getfocus, OBJHANDLE hNewVessel, OBJHANDLE hOldVessel) {
	// erase message if we focus to another vessel
	if (!getfocus) strcpy(oapiDebugString(), "");
}
H.
Code:
// ==============================================================
//                 ORBITER MODULE: LER2
//                  Part of the ORBITER SDK
//          Copyright (C) 2002-2004 Martin Schweiger
//                   All rights reserved
//
// LER2.cpp
// Control module for DRAGONFLYTITANvessel class
//
// Notes:
// This is an example for a "minimal" vessel implementation which
// only overloads the clbkSetClassCaps method to define vessel
// capabilities and otherwise uses the default VESSEL class
// behaviour.
// ==============================================================

//#ifndef __LER2_H
//#define __LER2_H

#include <UltraMath.h>
#include "orbitersdk.h"

// ==============================================================
// Some vessel parameters
// ==============================================================
const double MAXSPEED = 10; /* (2.78m/s = 10km/h) */
const double MASS = 450;
const double FUELMASS = 10;
const double RCS_ISP = 2900;
// Interface for derived vessel class: QJBStar
// ==========================================================

class DRAGONFLYTITAN : public VESSEL3 {
public:
	DRAGONFLYTITAN(OBJHANDLE hObj, int fmodel);
	void clbkSaveState(FILEHANDLE scn);
	void clbkSetClassCaps(FILEHANDLE cfg);
	void clbkLoadStateEx(FILEHANDLE scn, void *status);
	int clbkConsumeBufferedKey(DWORD key, bool down, char *kstate);
	void clbkVisualCreated(VISHANDLE vis, int refcount);
	void DefineAnimations(void);
	void clbkVisualDestroyed(VISHANDLE vis, int refcount);
	void clbkPostStep(double simtt, double simdt, double mjd);
	void clbkPreStep(double simt, double simdt, double mjd);
	void clbkFocusChanged(bool getfocus, OBJHANDLE hNewVessel, OBJHANDLE hOldVessel);



	

	
	//new
	

	PROPELLANT_HANDLE ph_main;
	THRUSTER_HANDLE th_hover[4];
	THRUSTER_HANDLE  thg_hover;


	//NEW
	
	
	
	//
	double  Height_From_Ground,Passo;

	//
	
	



};
 

kuddel

Donator
Donator
Joined
Apr 1, 2008
Messages
2,064
Reaction score
507
Points
113
...ever tried to simply Debug? Step by step...

And by the way: Member Passo is used, but never initialized!
 
Last edited:

dbeachy1

O-F Administrator
Administrator
Orbiter Contributor
Addon Developer
Donator
Beta Tester
Joined
Jan 14, 2008
Messages
9,214
Reaction score
1,560
Points
203
Location
VA
Website
alteaaerospace.com
Preferred Pronouns
he/him
If it helps, here are details on how to run Orbiter under the Visual Studio debugger to debug / put breakpoints in / step through your add-on's code: https://www.orbiter-forum.com/showthread.php?p=163799

In my experience, using the Visual Studio debugger is absolutely vital in developing good C++ code. Using the debugger allows you to step through your add-on's code one line at a time and inspect the contents of your code's variables as you go. It also halts instantly when a CTD occurs, which helps to pin down what caused the CTD.

EDIT:
In addition, it is a good idea to enable Visual Studio's runtime heap checks for debug builds to pin down memory usage bugs in your code. To do that, simply add this code block somewhere in the initialization of your DLL's code (for example, in the ovcInit method for vessels):

Code:
#ifdef _DEBUG
    // NOTE: _CRTDBG_CHECK_ALWAYS_DF is too slow
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF |
                   _CRTDBG_CHECK_CRT_DF | 
                   _CRTDBG_LEAK_CHECK_DF); 
#endif

That way, the debugger will halt when it detects memory being overwritten due to a pointer bug in your code. (A side note: you can OR in the _CRTDBG_CHECK_ALWAYS_DF flag if you have a really tricky memory bug that you cannot pin down using the existing flags there. However, enabling that flag slows down the code quite a bit, so I only enable that flag if and when I need it.)

One more note: be sure to build and run DEBUG builds during development, not Release builds! You should only build and test in Release mode to do final testing when the code is ready for public release.
 
Last edited:

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,636
Reaction score
2,613
Points
203
Location
Dallas, TX
Thanks. So where would I put the break. It loads and runs til I apply hover then ctd.
 

dbeachy1

O-F Administrator
Administrator
Orbiter Contributor
Addon Developer
Donator
Beta Tester
Joined
Jan 14, 2008
Messages
9,214
Reaction score
1,560
Points
203
Location
VA
Website
alteaaerospace.com
Preferred Pronouns
he/him
The first thing I would do is see where the CTD is occurring in your code. If you run your code under the debugger as detailed in my previous post, the debugger will halt when the CTD occurs. Then look at the method the CTD occurred in. Then you can put a breakpoint at the start of that method (or its caller, as necessary), restart Orbiter, and then step through the problem code.

The KEY, however, is to understand what each line of code is doing and inspect the value of the variables as you step through. That gets easier with practice, so hang in there. :)

Here is a video that demonstrates how to use the debugger in Visual Studio 2017 (the project code is in C#, but the principles are the same for C++):

 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,636
Reaction score
2,613
Points
203
Location
Dallas, TX
Thanks. Weird while running the debug no ctd on hover. BUt the craft doesn't fly correctly.

0Sa9xYt.jpg


but now it runs in regular mode

---------- Post added at 02:49 PM ---------- Previous post was at 11:17 AM ----------

So redid the TDpoint:
Code:
static const DWORD ntdvtx_geardown = 3;
static TOUCHDOWNVTX tdvtx_geardown[ntdvtx_geardown] = {
	{ _V(0, 0, 10), 1e6, 1e5, 1.6, 0.1 },
	{ _V(-3.5, 0, -1), 1e6, 1e5, 3.0, 0.2 },
	{ _V(3.5, 0, -1), 1e6, 1e5, 3.0, 0.2 } };

But now the hover quickly rises the vessel up and in orbit
Code:
	ph_main = CreatePropellantResource(FUELMASS);

	th_hover[0] = CreateThruster(_V(5, 0, 5), _V(0, 1, 0), 10/ 4, ph_main, RCS_ISP);
	th_hover[1] = CreateThruster(_V(-5, 0, 5), _V(0, 1, 0), 10 / 4, ph_main, RCS_ISP);
	th_hover[2] = CreateThruster(_V(5, 0, -5), _V(0, 1, 0), 10/ 4, ph_main, RCS_ISP);
	th_hover[3] = CreateThruster(_V(-5, 0, -5), _V(0, 1, 0), 10 / 4, ph_main, RCS_ISP);


	thg_hover = CreateThrusterGroup(th_hover, 4, THGROUP_HOVER);
 

kuddel

Donator
Donator
Joined
Apr 1, 2008
Messages
2,064
Reaction score
507
Points
113
Another thing that sometimes makes debugging hard (especially when dealing with CTDs) is that your stack might got corrupted somehow, so you can not easily track the point where the error occurred.

A usually good approach is to think about what should happen.
In our case: What method should be called when you apply hover....
clbkConsumeBufferedKey is a thing that comes to mind. Now set a break point there and step through in ever smaller steps until you either found no bug, or found the issue.

clbkPreStep rsp. clbkPostStep are also called very often, so these sometimes contain small bugs....working with break point in those methods however is 'kind of nerve wrecking as they are called very often :p


However, working with code that doesn't work usually teaches you the most!
Work with that. You have to climb the hill to get the fun down slide :p

---------- Post added at 00:36 ---------- Previous post was at 00:24 ----------

....and a little hint: The (API-)documentation also gives some hints on how the methods should behave.


Not only once did I thought I knew how a method should be implemented until I re-read the documentation and found out: I didn't
 
Last edited:

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,636
Reaction score
2,613
Points
203
Location
Dallas, TX
I thought I read about the not level having to do with the touchdown points. I tried Fred's code and the DG values and still a lot of pitch.

---------- Post added at 07:28 AM ---------- Previous post was at 06:31 AM ----------

So I used these values was able to lift off. not too much pitch. but drifts to the side.

Code:
const double MAXSPEED = 10; /* (2.78m/s = 10km/h) */
const double MASS = 4500;
const double FUELMASS = 1000;
const double RCS_ISP = 2900000000000;


Code:
	PROPELLANT_HANDLE ph_main;
	ph_main = CreatePropellantResource(FUELMASS);

	th_hover[0] = CreateThruster(_V(5, 0, 5), _V(0, 1, 0), 50000/ 4, ph_main, RCS_ISP);
	th_hover[1] = CreateThruster(_V(-5, 0, 5), _V(0, 1, 0), 50000 / 4, ph_main, RCS_ISP);
	th_hover[2] = CreateThruster(_V(5, 0, -5), _V(0, 1, 0), 50000/ 4, ph_main, RCS_ISP);
	th_hover[3] = CreateThruster(_V(-5, 0, -5), _V(0, 1, 0), 50000 / 4, ph_main, RCS_ISP);


	thg_hover = CreateThrusterGroup(th_hover, 4, THGROUP_HOVER);
 

4throck

Enthusiast !
Joined
Jun 19, 2008
Messages
3,502
Reaction score
1,008
Points
153
Location
Lisbon
Website
orbiterspaceport.blogspot.com
How about using fred's Vessel Builder for this ? Even if you need a C++ vessel latter on, all the parameters will be the same (mass, thruster locations and power, fuel, etc).
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,636
Reaction score
2,613
Points
203
Location
Dallas, TX
Thanks. did that. I got it up but the pitch changes. Since I added rcs I can horizon level. But the GS changes. Shouldn't that be 0 or small.

How can one make small altitude change?

I still like the movement via moving the Vessels lat and Long. BUt no altitude adjustment

---------- Post added at 08:41 AM ---------- Previous post was at 07:29 AM ----------

So by changing the touchdown Y value I can rise and lower. Not sure why the camera looking down direction doesn't seem to change
Code:
if (KEYDOWN(kstate, OAPI_KEY_NUMPAD7)) {

		//MOVEUP = 1;
		Height_From_Ground = Height_From_Ground + .1;
			SetTouchdownPoints(td, 4);
	}
	if (KEYDOWN(kstate, OAPI_KEY_NUMPAD9)) {

		//MOVEdown = 1;

	if (Height_From_Ground>0)	Height_From_Ground = Height_From_Ground - .1;
		SetTouchdownPoints(td, 4);
	}

Code:
void DRAGONFLYTITAN::SelectCockpitView(int CAM) {
	switch (CAM) {
	case 0: //FRONT
		SetCameraDefaultDirection(_V(0, 0, 1));
		SetCameraOffset(_V(0, height+1, 3.121));
		break;
	case 1: //bottom
		SetCameraDefaultDirection(_V(0, -1, 0));
		SetCameraOffset(_V(0, Height_From_Ground, 0));
		break;
	
	}
}
 

martins

Orbiter Founder
Orbiter Founder
Joined
Mar 31, 2008
Messages
2,448
Reaction score
462
Points
83
Website
orbit.medphys.ucl.ac.uk
Here is another option:

Since the quadcopter simulation problem had me intrigued, I have written a plugin for a generic quadcopter. It will be included in the next beta commit, whenever I find time to upload it. You are welcome to adapt the code for your Titan drone.Mine is currently Earth-based, so it will require adjustment for atmospheric and gravitational parameters, as well as vessel geometry.

I have so far implemented simple vertical velocity and attitude control, which makes it usable, but I also want to write some higher level autopilot modes, like flying to a specific point, or flying a course defined by waypoints. Possibly even following another vessel.

Btw. the mesh is my own, so it's going to be extremely basic - essentially just a placeholder, so you know where the copter is. If you or anybody else wants to contribute something better I'd be most grateful.
 

martins

Orbiter Founder
Orbiter Founder
Joined
Mar 31, 2008
Messages
2,448
Reaction score
462
Points
83
Website
orbit.medphys.ucl.ac.uk
I have uploaded a new Orbiter commit that includes the Quadcopter implementation (in Orbitersdk/samples/Vessel/Quadcopter). It's work in progress, but should be enough to play with the code.

There are currently three control loops implemented: vertical speed (controlled by manual throttle setting), pitch and bank attitude (controlled by manual pitch and roll input), and yaw velocity (controlled by manual yaw input).
Vertical speed is limited to +/-5m/s, and attitude is limited to 45degrees tilt. I've also implemented an "auto heading" mode that rotates the copter into the direction of movement for speeds above 5m/s. When it kicks in, the manual yaw control is disabled. I'm not sure if this is useful, but give it a go and disable it if you want.

You can also disable the control loops altogether and try direct control mode: RPM setting with throttle control, front/back RPM differentials with pitch controls, and left/right RPM differentials with roll controls. In practice this won't be very useful because it makes it very difficult to control the quadcopter.
 
Top