API Question How do I convert 1 vessel's thrust vector to another vessel's local vessel coordinates?

nbcfrosty

Active member
Joined
Jun 16, 2023
Messages
173
Reaction score
202
Points
43
Location
US
Hello. I want to transmit the child vessel's thrust forces to the parent. I am trying to do this:
Code:
VECTOR3 childThrustVector, globalThrust, parentLocalThrust;
        auto child = oapiGetVesselInterface(attach.child);
        child->GetThrustVector(childThrustVector);
        child->GlobalRot(childThrustVector, globalThrust);

        v->Global2Local(globalThrust, parentLocalThrust);
        
        v->AddForce(parentLocalThrust, attach.pos);

But in practice the parent vessel goes flying out of the atmosphere. Any help with this would be greatly appreciated.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,617
Reaction score
2,337
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
You must use a matrix there, there is no inverse function for GlobalRot. I thought about pairing Local2Global with Global2Local, but thats for positions, not forces.

If I am not wrong, its just GetRotationMatrix of your vessel transposed.
 

nbcfrosty

Active member
Joined
Jun 16, 2023
Messages
173
Reaction score
202
Points
43
Location
US
I haven't checked the numbers but testing with an SRB on DG this seems to work?

Code:
DLLCLBK void opcPreStep(double simt, double simdt, double mjd) {
    VESSEL* v = oapiGetFocusInterface();
    auto handle = v->GetHandle();
    if (attachments.find(handle) == attachments.end()) {
        return;
    }
    auto info = attachments[handle];
    for (int i = 0; i < info.attachments.size(); i++) {
        auto attach = info.attachments[i];
        if (!oapiIsVessel(attach.child)) {
            continue;
        }
        VECTOR3 childThrustVector, globalThrust, parentLocalThrust;
        auto child = oapiGetVesselInterface(attach.child);
        child->GetThrustVector(childThrustVector);
        child->Local2Global(childThrustVector, globalThrust);

        v->Global2Local(globalThrust, parentLocalThrust);
      
        v->AddForce(parentLocalThrust * simdt, _V(0, 0, 0));
    }
}

And this also seems to work:

Code:
VECTOR3 childThrustVector, globalThrust, parentLocalThrust;
        MATRIX3 R;
        auto child = oapiGetVesselInterface(attach.child);
        child->GetThrustVector(childThrustVector);
        child->GlobalRot(childThrustVector, globalThrust);
        v->GetRotationMatrix(R);
        parentLocalThrust = tmul(R, globalThrust);
        v->AddForce(parentLocalThrust * simdt, _V(0, 0, 0));
 
Last edited:

nbcfrosty

Active member
Joined
Jun 16, 2023
Messages
173
Reaction score
202
Points
43
Location
US
I also wanted to check if that the multiplication with simdt is right.
 

n72.75

Move slow and try not to break too much.
Orbiter Contributor
Addon Developer
Tutorial Publisher
Donator
Joined
Mar 21, 2008
Messages
2,696
Reaction score
1,353
Points
128
Location
Saco, ME
Website
mwhume.space
Preferred Pronouns
he/him
I also wanted to check if that the multiplication with simdt is right.
I don't think you want to to multiply by simdt. AddForce takes two arguments, a force vector, and a vector pointing to the point at which the force acts in local vessel coordinates relative to the center of mass.
 

n72.75

Move slow and try not to break too much.
Orbiter Contributor
Addon Developer
Tutorial Publisher
Donator
Joined
Mar 21, 2008
Messages
2,696
Reaction score
1,353
Points
128
Location
Saco, ME
Website
mwhume.space
Preferred Pronouns
he/him
I should also mention that if you're trying to make a vessel with multiple stages, it is probably far easier to do this with docking ports.
 

nbcfrosty

Active member
Joined
Jun 16, 2023
Messages
173
Reaction score
202
Points
43
Location
US
1690680032699.png
1690680128291.png
Trying to give my take on Kulch's UCGO Cargo Deck.

Code:
auto attach = info.attachments[i];
        if (!oapiIsVessel(attach.child)) {
            continue;
        }

        VECTOR3 childThrustVector, globalThrust, parentLocalThrust;
        MATRIX3 R;
        auto child = oapiGetVesselInterface(attach.child);
        child->GetThrustVector(childThrustVector);
        child->GlobalRot(childThrustVector, globalThrust);
        v->GetRotationMatrix(R);
        parentLocalThrust = tmul(R, globalThrust);
        v->AddForce(parentLocalThrust, attach.pos);

I think this is the final solution, I wasn't sure if I needed to multiply the force vector with simdt but looks like I don't need to.
 
Top