SDK Question Move a vessel relative to another

wingnut

Donator
Donator
Joined
May 10, 2013
Messages
129
Reaction score
0
Points
16
Hi,
I have an origin vessel and a target vessel which is moving relative to the origin vessel in relatively close vicinity. Now I want a third vessel to move on an intercept course from the origin to the target vessel. I think that I have the calculation of the aimpoint right but I cannot figure out how I change the intercept vessel's velocity so that it moves towards the calculated aimpoint.

1. is it in principle correct to do this with the DefSetState function?
2. I do the calculation of the aimpoints with the rvel and rpos attributes from the VESSELSTATE structure which are relative to the body being orbited, correct?
3. Subtracting the aimpoint from the origin vessel's position gives a vector from the origin to the aimpoint, right? Normalising this vector and multiplying it with the desired intercept velocity (used in the calculation of the aimpoint) would be the velocity vector of the intercept vessel relative to the origin if it were motionless, right?

How do I convert this to a vector which can be properly used in the VESSELSTATE? I tried Local2Rel but it results in a very lengthy vector, i. e. something in my code - and understanding of the refernce frames - is not correct.

Code:
double AimAhead(VECTOR3 delta, VECTOR3 vr, double interceptV) {
	double a = dotp(vr, vr) - interceptV * interceptV;
	double b = 2.0 * dotp(vr, delta);
	double c = dotp(delta, delta);

	double det = b*b - 4.0 * a * c;
	if(det > 0.0) {
		return 2.0 * c / (sqrt(det) - b);
	} else {
		return -1.0f;
	}
}

VECTOR3 targetPos, originPos, targetVelocity, originVelocity, delta, cv;

VESSELSTATUS vs;
VESSEL * originInterface = oapiGetFocusInterface();
OBJHANDLE originHandle = originInterface->GetHandle();
originInterface->GetStatus(vs);
originPos = vs.rpos;
originVelocity = vs.rvel;

vs.rpos.z += 100;
vs.rvel.x += 10;
VESSEL * targetInterface;
OBJHANDLE targetHandle = oapiCreateVessel("Target", "ShuttlePB", vs);
targetInterface = oapiGetVesselInterface(targetHandle);
targetInterface->GetStatus(vs);
targetPos = vs.rpos;
targetVelocity = vs.rvel;

originInterface->GetStatus(vs);
VESSEL * interceptInterface;
OBJHANDLE interceptHandle = oapiCreateVessel("Intercept", "Carina", vs);
interceptInterface = oapiGetVesselInterface(interceptHandle);

delta = targetPos - originPos;
cv = targetVelocity - originVelocity;
double interceptV = 15.0;
double t = AimAhead(delta, cv, interceptV);
		
if(t > 0.0) {
	VECTOR3 aimpoint = targetPos + (cv * t);
	VECTOR3 course = originPos - aimpoint;
	normalise(course);
	course = course * interceptV;
	Local2Rel(course, vs.rvel);
	interceptInterface->DefSetState(&vs);
}

Edit: I think it would be enough to add the course vector to the origin vessel's VESSELSTATUS.rvel vector but the components of the coordinates are twisted?
 
Last edited:

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Rather than setting the velocity directly, what about applying a force to the object in the desired direction? I think that's in local coordinates, and given that you know the mass of the object and the timestep duration, you should be able to find the needed force to get you to the desired velocity in a single timestep...
 

wingnut

Donator
Donator
Joined
May 10, 2013
Messages
129
Reaction score
0
Points
16
Mh, I did not know about this possibility. You mean something like this:
Code:
VECTOR3 course = originPos - aimpoint;
normalise(course);
double mass = interceptInterface->GetMass();
double force = mass * interceptV;
course = course * force;
VECTOR3 attackPoint; // what would be appropriate here?
interceptInterface->AddForce(course, attackPoint);
?

What should the attackPoint be? The vessels's COG? I tried a couple of unit vectors and it always results in the vessel moving into the same direction and much too slow...
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Mh, I did not know about this possibility. You mean something like this:
Code:
VECTOR3 course = originPos - aimpoint;
normalise(course);
double mass = interceptInterface->GetMass();
double force = mass * interceptV;
course = course * force;
VECTOR3 attackPoint; // what would be appropriate here?
interceptInterface->AddForce(course, attackPoint);
?

What should the attackPoint be? The vessels's COG? I tried a couple of unit vectors and it always results in the vessel moving into the same direction and much too slow...

COG (should be 0,0,0) would be fine for attackPoint.

The reason things are too slow is because you're not taking into account the timestep length. The force you're calculating would require it to act for a full second.

ClbkPreStep has a parameter which is the duration of the next timestep. So, you can divide interceptV by that timestep length in order to determine the needed acceleration to get to that interceptV in a single timestep, and then use that acceleration as input to calculate force.

In other words, you're currently doing force = mass * velocity, which isn't correct :) Need to use acceleration instead of velocity.
 

indy91

Addon Developer
Addon Developer
Joined
Oct 26, 2011
Messages
1,226
Reaction score
592
Points
128
I'm not sure if that directly helps you with your problem, but you could use the Clohessy-Wiltshire equations to calculate a rendezvous burn. It doesn't directly let you use a relative velocity magnitude as a parameter though, but instead the time until intercept.
 

wingnut

Donator
Donator
Joined
May 10, 2013
Messages
129
Reaction score
0
Points
16
The reason things are too slow is because you're not taking into account the timestep length. The force you're calculating would require it to act for a full second.
D'oh :facepalm:
Got it now, but the attackPoint in the COG does not really work to push the vessel into the right direction :eek:h:.
 

martins

Orbiter Founder
Orbiter Founder
Joined
Mar 31, 2008
Messages
2,448
Reaction score
462
Points
83
Website
orbit.medphys.ucl.ac.uk
The attack point has no influence on the linear acceleration induced by the acting force. It will however determine the angular acceleration. Setting the attack point to the CoG ([0,0,0] in vessel frame) simply ensures that it does not create an angular acceleration for any force direction.

In reality, creating a force precisely at the CoG will usually not be possible. Instead, a thruster position will be governed by vessel design constraints. This means that the thrust direction is also fixed if no angular acceleration should be induced. To match a target acceleration vector, the entire vessel must be rotated accordingly before firing the thruster.
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
D'oh :facepalm:
Got it now, but the attackPoint in the COG does not really work to push the vessel into the right direction :eek:h:.
The attackPoint doesn't have anything to do with the direction it goes--as Martin points out, it's just for the angular acceleration.

If the ship isn't going in the right direction, it's because your calculation of "course" is incorrect. I believe it should be done in the vessel's local frame--which would make "originPos" obviously 0,0,0; aimpoint should be the location of the other vessel in the current vessel's local frame.
 

wingnut

Donator
Donator
Joined
May 10, 2013
Messages
129
Reaction score
0
Points
16
Thank you both. I modified the code based on your suggestions and have the desired result now.
I had to multiply x,y,z components of my force vector for AddForce with -1 though as the intercept vessel was pushed in the exact opposite direction otherwise.
 
Top