Question Finding Relative Dock Coordinates

ADSWNJ

Scientist
Addon Developer
Joined
Aug 5, 2011
Messages
1,667
Reaction score
3
Points
38
I'm noodling round with some code to exploit Enjo's new HUD hooker, to do a docking overlay similar to the Dragon's display (Y P R , X Y Z to go ...).

I am looking for confirmation that this is the right way to determine a relative offset to the docking port (say port 0 on us, port 2 on target):

(v is our vessel, tv = target vessel)

Find the position of our port:

v->GetGlobalPos(vPos);
hD = v->GetDockHandle(0);
v->GetDockParams(hD,dRPos, ...,...)
dPos = vPos + dRPos;

Same for target:

hTV = oapiGetVesselByName("ISS");
tv = oapiGetVesselInterface(hTV)
tv->GetGlobalPos(tvPos);
hTD = tv->GetDockHandle(2);
v->GetDockParams(hTD,dTRPos, ...,...)
dTPos = tvPos + dTRPos;

Offset to dock:

dOfs = dPos - dTPos;


When I do this for a DV and ISS, docked, I get:

X = -3.78
Y = -17.39
Z = -18.85

I was expecting zeros? Anyone know why?


Orientation.cpp
Code:
#define STRICT
#define ORBITER_MODULE
#include "windows.h"
#include "stdio.h"
#include "orbitersdk.h"
#include "Orientation.h"

// ==============================================================
// Global variables

int g_MFDmode; // identifier for new MFD mode

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

DLLCLBK void InitModule (HINSTANCE hDLL)
{
	static char *name = "Orientation";   // MFD mode name
	MFDMODESPECEX spec;
	spec.name = name;
	spec.key = OAPI_KEY_T;                // MFD mode selection key
	spec.context = NULL;
	spec.msgproc = Orientation::MsgProc;  // MFD mode callback function

	// Register the new MFD mode with Orbiter
	g_MFDmode = oapiRegisterMFDMode (spec);
}

DLLCLBK void ExitModule (HINSTANCE hDLL)
{
	// Unregister the custom MFD mode when the module is unloaded
	oapiUnregisterMFDMode (g_MFDmode);
}

// ==============================================================
// MFD class implementation

// Constructor
Orientation::Orientation (DWORD w, DWORD h, VESSEL *vessel)
: MFD2 (w, h, vessel)
{
	v = vessel;
  hMyDock = v->GetDockHandle(0);
  v->GetDockParams(hMyDock, dMyDPos, dMyDDir, dMyDRot);

  font = oapiCreateFont (w/20, true, "Arial", FONT_NORMAL, 0);
	// Add MFD initialisation here

  hTgtV = oapiGetVesselByName("ISS");
  tv = oapiGetVesselInterface(hTgtV);


}

// Destructor
Orientation::~Orientation ()
{
	oapiReleaseFont (font);
	// Add MFD cleanup code here
}

// Return button labels
char *Orientation::ButtonLabel (int bt)
{
	// The labels for the two buttons used by our MFD mode
	static char *label[2] = {"UP", "DN"};
	return (bt < 2 ? label[bt] : 0);
}

// Return button menus
int Orientation::ButtonMenu (const MFDBUTTONMENU **menu) const
{
	// The menu descriptions for the two buttons
	static const MFDBUTTONMENU mnu[2] = {
		{"Move up", 0, '['},
		{"Move down", 0, ']'}
	};
	if (menu) *menu = mnu;
	return 2; // return the number of buttons used
}


// Repaint the MFD
bool Orientation::Update (oapi::Sketchpad *skp)
{
  int l;
  char buf[128];

	Title (skp, "Orientation");
	// Draws the MFD title

  simT = oapiGetSimTime();
  v->GetGlobalOrientation(gblOri);
  v->GetGlobalPos(gblPos);
  v->GetGlobalVel(gblVel);


  tv->GetGlobalPos(tvPos);
  hDock = tv->GetDockHandle(0);
  tv->GetDockParams(hDock, dPos, dDir, dRot);
  tvPos += dPos;
  relPos = gblPos + dMyDPos - tvPos;

	skp->SetFont (font);
	
  l = 2;
  sprintf_s(buf, "X %4.2f", relPos.x);
  skp->Text (W*10/100, H*l/25, buf, strlen(buf));//

  l++;
  sprintf_s(buf, "Y %4.2f", relPos.y);
  skp->Text (W*10/100, H*l/25, buf, strlen(buf));

  l++;
  sprintf_s(buf, "Z %4.2f", relPos.z);
  skp->Text (W*10/100, H*l/25, buf, strlen(buf));


	return true;
}

// MFD message parser
int Orientation::MsgProc (UINT msg, UINT mfd, WPARAM wparam, LPARAM lparam)
{
	switch (msg) {
	case OAPI_MSG_MFD_OPENED:
		// Our new MFD mode has been selected, so we create the MFD and
		// return a pointer to it.
		return (int)(new Orientation (LOWORD(wparam), HIWORD(wparam), (VESSEL*)lparam));
	}
	return 0;
}

Orientation.h
Code:
#ifndef __ORIENTATION_H
#define __ORIENTATION_H

class Orientation: public MFD2 {
public:
	Orientation (DWORD w, DWORD h, VESSEL *vessel);
	~Orientation ();
	char *ButtonLabel (int bt);
	int ButtonMenu (const MFDBUTTONMENU **menu) const;
	bool Update (oapi::Sketchpad *skp);
	static int MsgProc (UINT msg, UINT mfd, WPARAM wparam, LPARAM lparam);

protected:
	oapi::Font *font;
  VESSEL *v;

  VECTOR3 gblOri, gblOldOri;
  VECTOR3 gblPos, gblOldPos;
  VECTOR3 gblVel, gblOldVel;
  double simT, oldsimT;

  OBJHANDLE hTgtV;
  VESSEL *tv;
  VECTOR3 tvPos, relPos;

  DOCKHANDLE hDock, hMyDock;
  VECTOR3 dPos, dDir, dRot;
  VECTOR3 dMyDPos, dMyDDir, dMyDRot;

};

#endif // !__ORIENTTION_H
 

ADSWNJ

Scientist
Addon Developer
Joined
Aug 5, 2011
Messages
1,667
Reaction score
3
Points
38
I simplified my test by using the Smack! Scenario, with two DGs end to end, and I still didn't get a zero value for the docking point. It dawned on me that it's not sufficient just to use Global2Local to convert the XYZ cords into the local reference frame of the ship, but I also need to figure out how to rotate the local coordinates by the orientation of the ship. Without taking orientation into account, I think I am getting random numbers by blindly adding on the offset to my port, let alone doing that for the target ship.

Am I on the right track, guys?
 

martins

Orbiter Founder
Orbiter Founder
Joined
Mar 31, 2008
Messages
2,448
Reaction score
462
Points
83
Website
orbit.medphys.ucl.ac.uk
Yes, you need to rotate the local points into the global frame before adding them to the ships' global positions.

[math] \begin{array}{l} r_1^{(global)} = p^{(ship_1)} + R^{(ship_1)} r_1^{(local_1)}\\ r_2^{(global)} = p^{(ship_2)} + R^{(ship_2)} r_2^{(local_2)}\\ dr = r_1^{(global)} - r_2^{(global)} \end{array} [/math]Equivalently, you can map the target ship's docking position into the local frame of the source ship:
[math] \begin{array}{l} r_2^{(local_1)} = R^{T(ship_1)} [p^{(ship_2)} + R^{(ship_2)} r_2^{(local_2)} - p^{(ship_1)}]\\ dr = r_1^{(local_1)} - r_2^{(local_1)} \end{array} [/math]
VESSEL::Local2Global should take care of the rotations automatically.
 

ADSWNJ

Scientist
Addon Developer
Joined
Aug 5, 2011
Messages
1,667
Reaction score
3
Points
38
Thanks boss - that's exactly what I needed. On to the orientation and approach corridor next!
 
Top