SDK Question Touchdown points definition 2016

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,719
Reaction score
2,685
Points
203
Location
Dallas, TX
Pretty much unavoidable without hooking the suspension up to an animation.

Oh I would think that the vessel would be at the surface.

I meant that because of 3 touchdown points there would be some coverage of the wheels. So maybe I need to increase the Y. So I am riding the surface?
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,618
Reaction score
2,337
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
Oh I would think that the vessel would be at the surface.

I meant that because of 3 touchdown points there would be some coverage of the wheels. So maybe I need to increase the Y. So I am riding the surface?

Remember, Orbiter now simulates springs. How are those behaving, when you put weight on them?
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,719
Reaction score
2,685
Points
203
Location
Dallas, TX
Thanks. So the suspension animation will change? So on the LER it has 6 wheels. So each should changed based on what?
 

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,877
Reaction score
2,131
Points
203
Location
between the planets
Oh I would think that the vessel would be at the surface.

Yes, but since the touchdown points are simulating suspension, your altitude will still vary. As long as your wheels don't account for that, they'll dip into the ground.

Currently this is a bit tough to do (see my last few posts), so I hope the Doctor will implement some way to let us know the current compression of a touchdown point in the future.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,618
Reaction score
2,337
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
Thanks. So the suspension animation will change? So on the LER it has 6 wheels. So each should changed based on what?

To explain you what jedidia already found out: There is no way right now to query the current positions of the touchdown points from Orbiter to solve the animation. You only tell Orbiter with your definition: With 0N weight force on the suspension, your wheel would be at this position. And you tell it: By compressing the suspension by one meter, the spring force grows from 0N to x N. double the distance and the force doubles. Hookes Law implemented in Orbiters API.

One solution: You know at rest on Earth your touchdown point will be at a known position in the mesh. You know your spacecraft will weight about m kg. You have a spring constant of c. So, in your definition you add simply the following distance to your touchdown point in the mesh: [math]x = \frac{mg}{c}[/math]
So, you need to place your mesh right now either in a way, that it looks correct at equilibrium (all oscillations damped, flat surface, all springs compressed by weight). Or you calculate yourself, how far away each wheel is from the surface and animate it accordingly (which is the Pandoras Box of all solutions, because solving every small subproblem creates new problems to solve)



Also Orbiter uses a much simpler way of solving the suspension mechanisms (A simple linear spring, no unsprung weight) than it actually is in reality. Could be important for the rover animations, but I doubt anybody except mechanical engineers would notice the difference. Or Jeremy Clarkson.
 
Last edited:

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,719
Reaction score
2,685
Points
203
Location
Dallas, TX
Thanks. I guess I will wait. But nothing explains why my crawler spins around on the z axis
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,618
Reaction score
2,337
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
Thanks. I guess I will wait. But nothing explains why my crawler spins around on the z axis

We have one potential explanation in SSU, which can be summarized as:

There is no stable solution by Orbiters iterative solver to the differential equation system of the touchdown points because the initial guess presented in the scenario file is too far away from the solution, and thus, the PDE does not converge.

I suspect this applies especially to vehicles where the following factors make it much harder to find a solution:

  • High mass
  • Huge spring constant
 
Last edited:

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,719
Reaction score
2,685
Points
203
Location
Dallas, TX
?

Is there a way to make a vessel with no springs. Like a base has no springs. I could understand if I placed the crawler and it was ok. But then as it moved it spun around. But this happens when I place it.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,618
Reaction score
2,337
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
?

Is there a way to make a vessel with no springs. Like a base has no springs. I could understand if I placed the crawler and it was ok. But then as it moved it spun around. But this happens when I place it.

Use the old SetTouchdownPoints function?
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,618
Reaction score
2,337
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
I used the same touchdown points from 2010. In 2010 it works great but not in 2016.

Same mesh in both.

You only use the same numbers. You are not using the same API functions. You are not even using the same numbers for the same entity in the Orbiter API. The touchdown points in one function are different to the touchdown points in the other.

Its a bit said that I have to tell you this again but:

Stop guessing. Stop fooling yourself.

Know what the hell you are doing. Read the manual about what the functions do, which you want to use. Know what the numbers, which you give to Orbiter mean in that context. Be precise. Even a single changed word in a definition can change everything.

PS: And you should already know that the meshes in Orbiter doesn't matter. I can replace the Space Shuttle mesh in SSU by Donald Trump nude in Superman pose and it will still fly like a Space Shuttle. It only feels wrong.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,719
Reaction score
2,685
Points
203
Location
Dallas, TX
I have this in the class;
Code:
void SLSCRAWLER::clbkSetClassCaps(FILEHANDLE cfg) {
SetEmptyMass(2721000);
	SetSize(40);
	SetPMI(_V(133, 189, 89));

	SetSurfaceFrictionCoeff(0.005, 0.5);
	SetRotDrag (_V(0, 0, 0));
	SetCW(0, 0, 0, 0);
	SetPitchMomentScale(0);
	SetBankMomentScale(0);
	SetLiftCoeffFunc(0); 
 SetTouchdownPoints(_V(0, .001, 20), _V(-15, .001, -20), _V(15, .001, -20));;
This is the only place that sets the touchdown. Since in works in sc3/4 I wonder if it something else

The meshes do matter as far as the orientation.
 
Last edited:

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,618
Reaction score
2,337
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
The meshes do matter as far as the orientation.

No, not at all. Rotate the mesh by 180°, and your vessels Z-axis will still point forward. It only looks different from outside.
 

mike-c

Member
Joined
Jun 30, 2015
Messages
82
Reaction score
0
Points
6
TOUCHDOWNVTX reset?

Is there a way to modify TOUCHDOWNVTX during VESSEL-lifetime?

If i call
Code:
SetTouchdownPoints(tdvtx, NTDVTX);
in
Code:
clbkPreStep(double simt, double simdt, double mjd)
a second time (even with the same values), i find my vessel at NaN.

Thanks in advance...

---------- Post added at 11:48 PM ---------- Previous post was at 10:50 PM ----------

I have this in the class;
Code:
void SLSCRAWLER::clbkSetClassCaps(FILEHANDLE cfg) {
SetEmptyMass(2721000);
	SetSize(40);
	SetPMI(_V(133, 189, 89));

	SetSurfaceFrictionCoeff(0.005, 0.5);
	SetRotDrag (_V(0, 0, 0));
	SetCW(0, 0, 0, 0);
	SetPitchMomentScale(0);
	SetBankMomentScale(0);
	SetLiftCoeffFunc(0); 
 SetTouchdownPoints(_V(0, .001, 20), _V(-15, .001, -20), _V(15, .001, -20));;
This is the only place that sets the touchdown. Since in works in sc3/4 I wonder if it something else

The meshes do matter as far as the orientation.

If following could help:
this generic Launchpad-VESSEL sets up touchdown-points right after martins calculation, given above:

See here
300px-%D0%92%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9_%D1%82%D0%B5%D1%82%D1%80%D0%B0%D1%8D%D0%B4%D1%80.svg.png

Description
English: Regular tetrahedron and its circumscribed sphere.
Русский: Правильный вписанный тетраэдр ABCD.
Date 23 January 2014, 20:32:06
Source Own work
Author Illustr

It reads the common params (Mass[k], Size[m]) and the custom params (Base[m], RelTop[m]) from .cfg-file.
On a circle (in [math]xz\textrm{-plane}[/math] intersecting z =H-O-A at Base) TD[0]=[math]B[/math], TD[1]=[math]C[/math] and TD[2]=[math]D[/math] are placed in equal distance and "loaded" with Mass/3. Then above formulas are applied giving [math]k \textrm{ and } c[/math].
TD[3]=[math]A[/math] is placed in z=Base+RelTop, and an attachment placed right there (not so interesting for your purpose).
From this values TOUCHDOWNVTX -record is filled and set.
You find it in
Code:
void gLP::clbkSetClassCaps (FILEHANDLE cfg), line 110-167

I would like to have the TD1-3 to (extend,retract) on command to Level out uneven ground, but this seems not to work this way.

Anyway, here the little vessel (mark you, this will work only if CoG=_V(0,0,0) =[math]O[/math]):
Code:
// ==============================================================
//                 ORBITER MODULE: gLP
//
// gLP.cpp
// generic Launchpad
//
// ==============================================================

#define STRICT
#define ORBITER_MODULE

#include <windows.h>

#include "orbitersdk.h"
#include "resource.h"

#define _USE_MATH_DEFINES
#include <math.h>

#include <cstdio>

extern std::ostream cerr;

BOOL CALLBACK AboutDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);

// ==============================================================
// Some vessel parameters
// ==============================================================
const double  gLP_SIZE       = 20.0;             // mean radius [m]
const VECTOR3 gLP_CS         = {800,800,1600}; // x,y,z cross sections [m^2]
const VECTOR3 gLP_PMI        = {2.28,2.31,0.79};// principal moments of inertia (mass-normalised) [m^2]
const VECTOR3 gLP_RD         = {1,1,1};//{0.05,0.1,0.05};  // rotation drag coefficients
const double  gLP_EMPTYMASS  = 5e5;           // empty vessel mass [kg]
const double  gLP_FUELMASS   = 0.0;           // max fuel mass [kg]
const double  gLP_ISP        = 0;             // fuel-specific impulse [m/s]
const VECTOR3 gLP_TDP[3]     = {{0,-1.5,2},{-1,-1.5,-1.5},{1,-1.5,-1.5}}; // touchdown points [m]
const VECTOR3 gLP_COP        = {0,0,0};//{0,0,-0.1};      // centre of pressure for airfoils [m]

const VECTOR3 gLP_DOCK_POS   = {0,1.3,-1};      // docking port location [m]
const VECTOR3 gLP_DOCK_DIR   = {0,0,1};         // docking port approach direction
const VECTOR3 gLP_DOCK_ROT   = {0,1,0};        // docking port alignment direction


// ==============================================================
// gLP class interface
// ==============================================================

class gLP: public VESSEL3 {
public:
	gLP (OBJHANDLE hVessel, int flightmodel);
	~gLP ();
	void clbkSetClassCaps (FILEHANDLE cfg);
	int clbkConsumeBufferedKey(DWORD key, bool down, char *kstate);
	void shiftActor(int n, double m); 
	static BOOL CALLBACK ActorDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
	void  clbkPreStep(double simt, double simdt, double mjd); 

private:
	static void vlift (VESSEL *v, double aoa, double M, double Re,
		void *context, double *cl, double *cm, double *cd);
	static void hlift (VESSEL *v, double aoa, double M, double Re,
		void *context, double *cl, double *cm, double *cd);

	// transformations for control surface animations
	static MGROUP_ROTATE trans_Laileron, trans_Raileron;
	static MGROUP_ROTATE trans_Lelevator, trans_Relevator;

	ATTACHMENTHANDLE h0, h1;

	HWND hDlg;

	static const int NTDVTX = 4;
	TOUCHDOWNVTX tdvtx[NTDVTX];
	double Ytarget[4];
};

gLP::gLP (OBJHANDLE hVessel, int flightmodel)
: VESSEL3 (hVessel, flightmodel)
{
}

gLP::~gLP ()
{
}

// animation transformation definitions
static UINT GRP_LWING = 2;
static UINT GRP_RWING = 3;
static VECTOR3 LWING_REF  = {-1.3,-0.725,-1.5};
static VECTOR3 LWING_AXIS = {-0.9619,-0.2735,0};
static VECTOR3 RWING_REF  = {1.3,-0.725,-1.5};
static VECTOR3 RWING_AXIS = {0.9619,-0.2735,0};
static float AILERON_RANGE = (float)(20.0*RAD);
static float ELEVATOR_RANGE = (float)(30.0*RAD);
MGROUP_ROTATE gLP::trans_Laileron (0, &GRP_LWING, 1, LWING_REF, LWING_AXIS, AILERON_RANGE);
MGROUP_ROTATE gLP::trans_Raileron (0, &GRP_RWING, 1, RWING_REF, RWING_AXIS, AILERON_RANGE);
MGROUP_ROTATE gLP::trans_Lelevator (0, &GRP_LWING, 1, LWING_REF, LWING_AXIS, -ELEVATOR_RANGE);
MGROUP_ROTATE gLP::trans_Relevator (0, &GRP_RWING, 1, RWING_REF, RWING_AXIS, ELEVATOR_RANGE);

HINSTANCE htheModule;
static gLP* theVessel;

// ==============================================================
// Overloaded callback functions
// ==============================================================

// --------------------------------------------------------------
// Set the capabilities of the vessel class
// --------------------------------------------------------------
void gLP::clbkSetClassCaps (FILEHANDLE cfg)
{
	//THRUSTER_HANDLE th_main, th_hover, th_rcs[14], th_group[4];

	// physical vessel parameters
	SetSize(gLP_SIZE);
	SetEmptyMass (gLP_EMPTYMASS);
	SetPMI (gLP_PMI);
	SetCrossSections (gLP_CS);
	SetRotDrag (gLP_RD);

	// evaluate config-file
	double lMass, lSize, lBase=0.0, lTop=1.0;
	double x=0,y=0,z=0;
	double Base, Top;

	char *line;
	char lmesh[80];
	while(oapiReadScenario_nextline (cfg, line)){
		if (!_strnicmp (line, "Mass =", 4)){
			sscanf(line+6, "%lf", &lMass);
			SetEmptyMass(lMass);
		}else if(!_strnicmp (line, "Size =", 4)){
			sscanf(line+6, "%lf", &lSize);
			SetSize(lSize);
		}else if(!_strnicmp (line, "Base =", 4)){
			sscanf(line+6, "%lf", &lBase);
		}else if(!_strnicmp (line, "RelTop =", 6)){
			sscanf(line+8, "%lf", &lTop);
		}
	};
	//sprintf(oapiDebugString(), "Base: %lf ; RolTop: %lf", lBase, lTop);
	Base=lBase; Top=lTop+Base;
	if(Top<Base) Top=Base+(-lTop);

	//SetTouchdownPoints
	VECTOR3 td0, td1, td2, td3;
	TOUCHDOWNVTX vtxtmp;

	double lZ0=GetSize(); double lX1=lZ0/sqrt(3.0);
	td0 = _V(0,Base,lZ0);
	td1 = _V(-lX1,Base,-lZ0/2);
	td2 = _V(lX1,Base,-lZ0/2);
	td3 = _V(0,Top,0);

	double k = -9.81*(GetEmptyMass()/3)/-0.5;
	double c = .95*2*sqrt(GetEmptyMass()*k);

	vtxtmp.pos=td0; vtxtmp.stiffness = k; vtxtmp.damping=c; vtxtmp.mu=3;
	tdvtx[0]=	vtxtmp; Ytarget[0]=td0.y;
	vtxtmp.pos=td1;
	tdvtx[1]=	vtxtmp; Ytarget[1]=td1.y;
	vtxtmp.pos=td2;
	tdvtx[2]=	vtxtmp; Ytarget[2]=td2.y;
	vtxtmp.pos=td3;
	tdvtx[3]=	vtxtmp; Ytarget[3]=td3.y;

	SetTouchdownPoints(tdvtx, NTDVTX);

	// attachment port definitions
	h0=CreateAttachment(true, _V(0,Top,0), _V(0,1,0), _V(0,0,-1), "fVessel");
	h0=CreateAttachment(false, _V(0,Top,0), _V(0,1,0), _V(0,0,-1), "tVessel");

	// airfoil definitions
	

	// control surface animations
	

	// aerodynamic control surface defintions
	

	// propellant resources
	

	// main engine
	

	// hover engine
	

	// RCS engines
	
	// camera parameters
	SetCameraOffset (_V(0,20.0,10.0));

	// associate a mesh for the visual
	//AddMesh ("blc1arms");
	//AddMesh ("blc1arms_base");
}

int gLP::clbkConsumeBufferedKey(DWORD key, bool down, char *kstate){
	if (key == OAPI_KEY_SPACE  && down && KEYMOD_CONTROL (kstate) && !KEYMOD_ALT(kstate)){
		hDlg = CreateDialogParamA(htheModule, MAKEINTRESOURCE(IDD_ABOUT),  GetActiveWindow(), ActorDlgProc,(LPARAM)this);
		ShowWindow(hDlg, SW_SHOW);
		return 1;
	}
	return 0;
}

void  gLP::clbkPreStep(double simt, double simdt, double mjd){
	// does not work
	/*for(int i=0; i<4; i++){
		if(tdvtx[i].pos.y < (Ytarget[i]-0.001)){
			tdvtx[i].pos.y += 0.00001;
			SetTouchdownPoints(tdvtx, NTDVTX);
		}
		else if(tdvtx[i].pos.y > (Ytarget[i]+0.001)){
			tdvtx[i].pos.y -= 0.00001;
			SetTouchdownPoints(tdvtx, NTDVTX);
		}
	}*/
}


BOOL CALLBACK gLP::ActorDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    switch(Message)
    {
        case WM_INITDIALOG:
			theVessel=(gLP*)lParam;
        return TRUE;
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case IDOK:
                    EndDialog(hwnd, IDOK);
                break;
                case IDCANCEL: 
                    DestroyWindow(hwnd); 
                    // = NULL; 
                    return TRUE;
                break;
            }
        break;
        default:
            return FALSE;
    }
    return TRUE;
}

void gLP::shiftActor(int n, double m){
	// does not work
	//if((n > -1)&(n<4)) Ytarget[n] += m;
}

// ==============================================================
// Airfoil lift/drag functions
// ==============================================================

void gLP::vlift (VESSEL *v, double aoa, double M, double Re,
	void *context, double *cl, double *cm, double *cd)
{
	/*static const double clp[] = {  // lift coefficient from -pi to pi in 10deg steps
		-0.1,-0.5,-0.4,-0.1,0,0,0,0,0,0,0,0,0,0,-0.2,-0.6,-0.6,-0.4,0.2,0.5,0.9,0.8,0.2,0,0,0,0,0,0,0,0,0,0.1,0.4,0.5,0.3,-0.1,-0.5
	};*/
	*cl=0.0; *cm=0.0; *cd=0.0;
	
}

void gLP::hlift (VESSEL *v, double aoa, double M, double Re,
	void *context, double *cl, double *cm, double *cd)
{
	/*static const double clp[] = {  // lift coefficient from -pi to pi in 45deg steps
		0,0.4,0,-0.4,0,0.4,0,-0.4,0,0.4
	};*/
	*cl=0.0; *cm=0.0; *cd=0.0;
}

// ==============================================================
// API callback interface
// ==============================================================

// --------------------------------------------------------------
// Vessel initialisation
// --------------------------------------------------------------
DLLCLBK VESSEL *ovcInit (OBJHANDLE hvessel, int flightmodel)
{
	return new gLP (hvessel, flightmodel);
}

// --------------------------------------------------------------
// Vessel cleanup
// --------------------------------------------------------------
DLLCLBK void ovcExit (VESSEL *vessel)
{
	if (vessel) delete (gLP*)vessel;
}

DLLCLBK void InitModule(HINSTANCE  hModule){
	htheModule = hModule;
}

BOOL CALLBACK ActorDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    switch(Message)
    {
        case WM_INITDIALOG:
			theVessel=(gLP*)lParam;
        return TRUE;
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
				case IDY1INC:
					theVessel->shiftActor(0,0.01);
				break;
				case IDY1DEC:
					theVessel->shiftActor(0,-0.01);
				break;
				case IDY2INC:
					theVessel->shiftActor(1,0.01);
				break;
				case IDY2DEC:
					theVessel->shiftActor(1,-0.01);
				break;
				case IDY3INC:
					theVessel->shiftActor(2,0.01);
				break;
				case IDY3DEC:
					theVessel->shiftActor(3,-0.01);
				break;
                case IDOK:
                    DestroyWindow(hwnd); 
                    return TRUE;
                break;
                case IDCANCEL:
                    EndDialog(hwnd, IDCANCEL);
                break;
            }
        break;
        default:
            return FALSE;
    }
    return TRUE;
}
:cheers:
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,719
Reaction score
2,685
Points
203
Location
Dallas, TX
Well. In my case it wasn't the touchdown points casuing the issue. I gutted the cpp and h. So basic info telling which mesh. The issue is on how it moves.

Shuttle A has code where the touchdown and gear move.
 

mike-c

Member
Joined
Jun 30, 2015
Messages
82
Reaction score
0
Points
6
Well. In my case it wasn't the touchdown points casuing the issue. I gutted the cpp and h. So basic info telling which mesh. The issue is on how it moves.

Shuttle A has code where the touchdown and gear move.

Anyway, good news if your crawler is crawling now.

:tiphat: will follow your hint
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,719
Reaction score
2,685
Points
203
Location
Dallas, TX
Not sure why making the Y value more negative raises the vessel above the ground?

VpAeR0B.jpg

You can see the lower value is 0

Code:
SetTouchdownPoints(_V(0, .001, 20), _V(-15, .001, -20), _V(15, .001, -20));;

put the vessel on the ground.

Code:
	SetTouchdownPoints(_V(0, 5.45, 20), _V(-15, 5.45, -20), _V(15, 5.45, -20));;
but this places the mesh/vessel into the ground.

if I use this:
Code:
SetTouchdownPoints(_V(0, -15.55, 20), _V(-15, -15.45, -20), _V(15, -15.45, -20));;
I should be 12.17 alt. and about 8 degrees down in pitch. not sure why?
 
Top