Install Steam
login
|
language
简体中文 (Simplified Chinese)
繁體中文 (Traditional Chinese)
日本語 (Japanese)
한국어 (Korean)
ไทย (Thai)
Български (Bulgarian)
Čeština (Czech)
Dansk (Danish)
Deutsch (German)
Español - España (Spanish - Spain)
Español - Latinoamérica (Spanish - Latin America)
Ελληνικά (Greek)
Français (French)
Italiano (Italian)
Bahasa Indonesia (Indonesian)
Magyar (Hungarian)
Nederlands (Dutch)
Norsk (Norwegian)
Polski (Polish)
Português (Portuguese - Portugal)
Português - Brasil (Portuguese - Brazil)
Română (Romanian)
Русский (Russian)
Suomi (Finnish)
Svenska (Swedish)
Türkçe (Turkish)
Tiếng Việt (Vietnamese)
Українська (Ukrainian)
Report a translation problem
But yeah. get the coordinates of ship and destination, gyro override to point ship to destination, thruster override, monitor distance to destination, reverse thruster override some distance before reaching target, maybe fine tune position/orientation a little, and done.
Edit: If you just want hints, then "Yes to matrix". Look into Block.WorldMatrix.Forward
VRageMath.Vector3D SP=Source.GetPosition(); //Get source position
VRageMath.Vector3D SF=Source.GetPosition()+Source.WorldMatrix.Forward; // Get source forward/up/right
VRageMath.Vector3D SU=Source.GetPosition()+Source.WorldMatrix.Up;
VRageMath.Vector3D SR=Source.GetPosition()+Source.WorldMatrix.Right;
double D=(SP-Target).Length(); //Get magnitudes of vectors to target
double P=Math.Acos(((SU-Target).Length()*(SU-Target).Length()-(SU-SP).Length()*(SU-SP).Length()-D*D)/(-2*(SU-SP).Length()*D));
double Y=Math.Acos(((SR-Target).Length()*(SR-Target).Length()-(SR-SP).Length()*(SR-SP).Length()-D*D)/(-2*(SR-SP).Length()*D));
double PitchDeg=90-(P*180/Math.PI); //Radians to degrees
double YawDeg=90-(Y*180/Math.PI);
if (D<(SF-Target).Length()) PitchDeg=180-PitchDeg; //Normalize and convert to degrees
if (PitchDeg>180) PitchDeg=-(360-PitchDeg);
if (D<(SF-Target).Length()) YawDeg=180-YawDeg;
if (YawDeg>180) YawDeg=-(360-YawDeg);
PitchD=PitchDeg; //Outputs
YawD=YawDeg;}
I use the ship cockpit as the source, destination coordinate, and get the return pitch and yaw.
In my test, I set up a target ship on a heading with thrust override set reasonably low so I can retrieve it later. On my ship, I used a camera raycast to determine target ship position and speed, used algebra to determine its location one minute in the future, used that for target position, got the pitch and yaw, oriented my ship for that, waited the minute and target was perfectly passed in front of my ship.
This all has some good information in it that could help me for sure, but my question is how do you figure these equations out by yourself? I would love to be self efficient and I know that every coder has to look at references, but I feel as if some people just know these things better than I do and I would love to understand how I could get to that level.
How to figure out the equations? I just search the web because I know others have had the same question. I'm fairly good at knowing which terms to use when searching, and I think these equations came from wikipedia. Its probably in my old textbooks as well. I don't have time or ambition to re-study enough algebra to come up with it myself and it'd be a waste of time. Don't need to recreate the wheel.
How to figure out the values within the equations? This is the hard part. Reading through the Space Engineers block definitions. Some of things are labeled wrong or have an undocumented scale or other problems. Is Block.Angle in degrees or radians? Block.Position is different than Block.GetPosition().
Thanks for all of the help btw. I've been working constantly these past couple of days on this project and I finally got it to work. I have another question for you if you're up for it. I want to calculate the predicted location of a moving target now.
I know I'll need: Distance over a specified time & the directional heading of a target.
I see in the game with Raycasting that velocity is measured by each coordinate grid, but the API doesn't specify the unit of measurement that velocity is measured in.
So that leaves me with two theory's on how I would go about this:
1. Multiply velocity by (Gameticks = 5 seconds) to get distance, then determine the target facing and add that distance to it's directional value
OR
2. Velocity is measured in this format with Raycasting: X: ? Y: ? Z: ?
So, again, multiply velocity by (Gameticks = 5 seconds), then add the new Velocity measurements to the current POS of the "target"
To me it sounds like both of these could work, and I don't expect you have the perfect answer, but your opinion would be well appreciated!
https://steamcommunity.com/app/244850/discussions/0/5154944131333685552/#c5154944131333798774
Gotcha. Need a camera for raycast if that wasn't obvious. I prefer to get my raycast as center of camera going out as a line, but you can tilt a bit with camera settings. Its in a line, not a cone. Detected entity has a timestamp on it, but is unreliable so you'll have to make your own time stamp or use the one in the example I'm providing. This is what I use as a disorganized bunch and might not be the most optimal, but I like it.
long TIMESTAMP=0; // Time stamp of last scanned target
public void Main(string argument, UpdateType updateSource) {
IMyCameraBlock CAM=GridTerminalSystem.GetBlockWithName("Camera") as IMyCameraBlock;
double MaxDesiredRange=15000.0; // Max range you want to scan in meters
CAM.EnableRaycast=(!CAM.CanScan(MaxDesiredRange)); // Enables/disables charging of raycast at 2000m per second to MaxDesiredRange
Echo("Camera raycast available range is "+CAM.AvailableScanRange.ToString("0"));
if (argument=="SCAN") {
//float Pitch=0, Yaw=0;
//TARGET=CAM.Raycast(CAM.AvailableScanRange,Pitch,Yaw); // Raycast with pitch and yaw
TARGET=CAM.Raycast(CAM.AvailableScanRange); // Do a raycast and get result
TIMESTAMP=System.DateTime.UtcNow.Ticks; }
if (TARGET.IsEmpty()) {
Echo("No target"); }
else {
Echo("Target "+TARGET.Name);
// Calculate current position by (old target position + (target speed * time since scanned)
Vector3D POSITION=TARGET.Position+TARGET.Velocity*((System.DateTime.UtcNow.Ticks-TIMESTAMP)/10000000); // Projected position
Echo("Current Position X="+POSITION.X.ToString("0")+" Y="+POSITION.Y.ToString("0")+" Z="+POSITION.Z.ToString("0")); } }
Of course, I can provide explanations or more detail if requested.
My idea worked, I can predict target locations now over time. I have a question for you about your code from earlier.
I'll be talking about this line specifically since it's the only line I don't understand:
double P=Math.Acos(((SU-Target).Length()*(SU-Target).Length()-(SU-SP).Length()*(SU-SP).Length()-D*D)/(-2*(SU-SP).Length()*D));
(Use this link for a triangle reference on the sides and angles I will be talking about :
https://i.stack.imgur.com/YfkK5.jpg)
I see you are basically drawing a right triangle from each position of the IMyTerminalBlock to the target's position by subtracting each way and then squaring it. I also know your end goal is to get Angle a, which is why you use cosine.
But here is where I get confused.
If I were to label the whole equation down to it's simplest form,
The Numerator would end up looking like : c^2 - b^2 - a^2
The Denominator would end up looking like : (-2)(b)(a)
And the whole thing would be inside of angular cos.
For the Numerator, you're using Pythagorean Theorem by what I can see. Except, wouldn't the numerator = 0 no matter what since a^2 + b^2 = c^2, meaning c^2 - b^2 - a^2 would have to equal 0? Which means no matter what the denominator is, the equation would always be equal to 0? I must be wrong since it make's no sense to do all that math for it to just always be 0.
For the Denominator, I just simply don't know why we ended up doing (-2)(b)(a) lol.
I tried finding a similar equation online, but couldn't. If you care to go into detail, I would love to learn about this equation. Sorry for the absolute wall chunk
Scratch that, you're using the Cosine Rule to find the angle I see that now. My only ACTUAL question now is why you used (-2)(b)(a) in the Denominator instead of positive 2
I don't think I'm using (-2)(b)(a) in the way you think I am. In order for the result to be (+2) the product of (b)(a) would have to be (-1) and that is never the case in my displayed values. I've done a full circle in pitch and yaw and a 45 degree.
I do now see where I'm probably overdoing some calculations, which I have tagged for later study. I'm pleased with it the way it is for now though.
VRageMath.Vector3D SF=Source.GetPosition()+Source.WorldMatrix.Forward; // Get direction references
VRageMath.Vector3D SU=Source.GetPosition()+Source.WorldMatrix.Up;
VRageMath.Vector3D SR=Source.GetPosition()+Source.WorldMatrix.Right;
double Dist=(Source.GetPosition()-Target).Length(); //Get magnitudes of vectors.
double DistF=(SF-Target).Length();
double DistU=(SU-Target).Length();
double DistR=(SR-Target).Length();
double PitchRad=Math.Acos((DistU*DistU-1-Dist*Dist)/(-2*Dist)); //Use law of cosines to determine angles.
double YawRad=Math.Acos((DistR*DistR-1-Dist*Dist)/(-2*Dist));
double PitchDeg=90-(PitchRad*180/Math.PI); //Radians to degrees.
double YawDeg=90-(YawRad*180/Math.PI);
if (Dist<DistF) PitchDeg=180-PitchDeg; //Normalize angles
if (PitchDeg>180) PitchDeg=-(360-PitchDeg);
if (Dist<DistF) YawDeg=180-YawDeg;
if (YawDeg>180) YawDeg=-(360-YawDeg);
Pitch=PitchDeg; //Outputs
Yaw=YawDeg; }
The matrix for the new orientation and position will be calculated for you from the yaw, pitch, roll and position. If you must calculate the matrix this is pretty simple to do. Rows 0, 1 and 2 should be X, Y and Z and row 4 is translation. Transform your base vectors by axis angle matrices formed from which axis to rotate around for yaw (up), pitch (right) and roll (look). Put these vectors into rows 0, 1 and 2 with column 0 being 0. Then translation goes into row 4 and the 4th value (or W) in row 4 is 1.0f.
X Right,X, Right.Y, Right.Z, 0.0f
Y Up.X, Up.Y, Up.Z, 0.0f
Z Look.X, Look.Y, Look.Z, 0.0f
W Translation.X, Translation.Y, Translation.Z, 1.0f
Again the handedness of the coordinate system matters. I do not know what SE uses. DX uses a right hand system. Right is +X, Up is +Y and Look is +Z or into the screen.