1. This forum is obsolete and read-only. Feel free to contact us at support.keenswh.com

The IMyRemoteControl and IMyShipController update

Discussion in 'Programming (In-game)' started by Malware, May 20, 2016.

Thread Status:
This last post in this thread was made more than 31 days old.
  1. Malware

    Malware Master Engineer

    Messages:
    9,867
    Apparently the documentation file isn't being generated any more, so I'll just pop the interfaces here for your perusal.

    IMyRemoteControl.cs
    Code:
        /// <summary>
        /// Provides basic information about a waypoint.
        /// </summary>
        public struct MyWaypointInfo
        {
            /// <summary>
            /// The waypoint name
            /// </summary>
            public readonly string Name;
    
            /// <summary>
            /// The coordinates of this waypoint
            /// </summary>
            public readonly Vector3D Coords;
    
            public MyWaypointInfo(string name, Vector3D coords)
            {
                Name = name;
                Coords = coords;
            }
        }
    
        public interface IMyRemoteControl : IMyShipController
        {
            // Gets the nearest player's position. Will only work if the remote control belongs to an NPC
            bool GetNearestPlayer(out Vector3D playerPosition);
    
            /// <summary>
            /// Removes all existing waypoints.
            /// </summary>
            void ClearWaypoints();
    
            /// <summary>
            /// Gets basic information about the currently configured waypoints.
            /// </summary>
            /// <param name="waypoints"></param>
            void GetWaypointInfo(List<MyWaypointInfo> waypoints);
    
            /// <summary>
            /// Adds a new waypoint.
            /// </summary>
            /// <param name="coords"></param>
            /// <param name="name"></param>
            void AddWaypoint(Vector3D coords, string name);
    
            /// <summary>
            /// Enables or disables the autopilot.
            /// </summary>
            /// <param name="enabled"></param>
            void SetAutoPilotEnabled(bool enabled);
    
            /// <summary>
            /// Determines whether the autopilot is currently enabled.
            /// </summary>
            bool IsAutoPilotEnabled { get; }
    
            // CH: TODO: Uncomment later for drones
            Vector3D GetFreeDestination(Vector3D originalDestination, float checkRadius, float shipRadius);
        }
    
    
    IMyShipController.cs
    Code:
        public struct MyShipMass
        {
            /// <summary>
            /// Gets the base mass of the ship.
            /// </summary>
            public readonly int BaseMass;
    
            /// <summary>
            /// Gets the total mass of the ship, including cargo.
            /// </summary>
            public readonly int TotalMass;
           
            public MyShipMass(int mass, int totalMass) : this()
            {
                BaseMass = mass;
                TotalMass = totalMass;
            }
        }
    
        public struct MyShipVelocities
        {
            /// <summary>
            /// Gets the ship's linear velocity (motion).
            /// </summary>
            public readonly Vector3D LinearVelocity;
           
            /// <summary>
            /// Gets the ship's angular velocity (rotation).
            /// </summary>
            public readonly Vector3D AngularVelocity;
    
            public MyShipVelocities(Vector3D linearVelocity, Vector3D angularVelocity) : this()
            {
                LinearVelocity = linearVelocity;
                AngularVelocity = angularVelocity;
            }
        }
    
        public interface IMyShipController : IMyTerminalBlock
        {
            /// <summary>
            /// Indicates whether a block is locally or remotely controlled.
            /// </summary>
            bool IsUnderControl { get; }
    
            /// <summary>
            /// Indicates whether wheels are being controlled by this controller.
            /// </summary>
            bool ControlWheels { get; }
    
            /// <summary>
            /// Indicates whether thrusters are being controlled by this controller.
            /// </summary>
            bool ControlThrusters { get; }
    
            /// <summary>
            /// Indicates the current state of the handbrake.
            /// </summary>
            bool HandBrake { get; }
    
            /// <summary>
            /// Indicates whether dampeners are currently enabled.
            /// </summary>
            bool DampenersOverride { get; }
    
            /// <summary>
            /// Gets the detected natural gravity vector and power at the current location.
            /// </summary>
            /// <returns></returns>
            Vector3D GetNaturalGravity();
    
            /// <summary>
            /// Gets the detected artificial gravity vector and power at the current location.
            /// </summary>
            /// <returns></returns>
            Vector3D GetArtificialGravity();
    
            /// <summary>
            /// Gets the total accumulated gravity vector and power at the current location, 
            /// taking both natural and artificial gravity into account.
            /// </summary>
            /// <returns></returns>
            Vector3D GetTotalGravity();
    
            /// <summary>
            /// Gets the basic ship speed in meters per second, for when you just need to know how fast you're going.
            /// </summary>
            /// <returns></returns>
            double GetShipSpeed();
    
            /// <summary>
            /// Determines the linear velocities in meters per second and angular velocities in radians per second. 
            /// Provides a more accurate representation of the directions and axis speeds.
            /// </summary>
            MyShipVelocities GetShipVelocities();
    
            /// <summary>
            /// Gets information about the current mass of the ship.
            /// </summary>
            /// <returns></returns>
            MyShipMass CalculateShipMass();
        }
    
    
    The use of these should be apparent enough. If not, don't hesitate to ask!
     
    • Like Like x 3
    • Informative Informative x 1
  2. Seamus Donohue

    Seamus Donohue Trainee Engineer

    Messages:
    90
    W00T! Thank you!

    I just have a few questions:

    1) Is AngularVelocity relative to local ship axes or are they relative to the world? For example, if a ship is spinning around the ship's own Z-axis, but the ship's Z-axis is parallel to the world's Y-axis, then is the spin going to be reported as a Z-spin or a Y-spin?

    2) What units are the angular velocities in? (I would assume radians/second, but wanted to check.)

    3) Does each AngularVelocity component follow the right-handed or left-handed rule? For example, if it's the right handed rule, and a ship has a positive Z-axis spin, then the thumb of the right hand points in the direction of positive-Z and the fingers of the right hand curl in the direction that the ship is spinning.
     
  3. Malware

    Malware Master Engineer

    Messages:
    9,867
    1) I honestly have no idea :p I don't (currently) have any use for this particular property myself, which means I'm afraid it never even crossed my mind that it might be world-relative... I fear it might be. You're going to have to experiment, and please post your findings here - I'm sure others would love that information as well. Besides, if the angular velocity is relative to the world and not the ship, I think it should be considered a bug, should be reported as such and changed - so it's more intuitive. If that's easy to do, that is...

    2) Radians per second, yes.

    3) Again I don't know, but since the linear velocity is left-handed (-Z is forward in case I've confused the terms again) I must assume that so is the AngularVelocity.
     
  4. Seamus Donohue

    Seamus Donohue Trainee Engineer

    Messages:
    90
    I'll experiment with it tonight.

    The coordinate axes are all right-handed. Hold out your right hand flat. Stick your thumb out to the side. Your fingers face +X, your palm faces +Y, your thumb points in +Z.
     
  5. Innoble

    Innoble Apprentice Engineer

    Messages:
    238
    This is so awesome. Mass, velocity and angular velocity! That is going to make so many PB scripts so much more compact and easier to use. This will also save on CPU time as the ways the PB used to calculate these things is a lot more CPU intensive.

    Is there also a way to get a Vector3D for the center of mass location? That would be perfect.
     
  6. ZerothAngel

    ZerothAngel Trainee Engineer

    Messages:
    25
    Hey @Malware, thanks for the additions.

    I briefly experimented with them last night, and it seems that TotalMass is the same as what's displayed in the UI. In other words, it doesn't take inventory scaling into account. Is that mass value available anywhere? (Either the scaled total mass or the world's inventory scale.)

    As far as I understand it, a ship with 500t of cargo will perform differently in a world with 1X inventory vs. 10X inventory. So the "physics mass" will be some other value.

    And lastly... were they added to IMyShipController because that's where the information was readily available? To me, it seems like they should instead be properties of IMyCubeGrid. Though I guess in an "RP"ish sort-of way, I can see why getting these type of values from a ship controller would make sense. Though oddly, passenger seats, cryo chambers, etc. are also ship controllers (and yes, you can pull these values from them as well if they're the only ship controller you have... which is funny in a way).
     
  7. Malware

    Malware Master Engineer

    Messages:
    9,867
    Yes, TotalMass is the same that is displayed in the UI. That's the whole point. It's what's available to the player, so it's what's available to the programmable block. If that value is incorrect as far as inventory handling goes, then that means something is screwy about the scaling. [edit] I forgot to add - that's quite annoying if this is so.

    I do what I can to avoid exposing meta-information to the programmable block since it's an ingame device and should be privy to the in-game rules.

    @Innoble unfortunately not - that I know of at least.
     
    Last edited: May 20, 2016
  8. ZerothAngel

    ZerothAngel Trainee Engineer

    Messages:
    25
    I agree with you in principle, but now we have AngularVelocity, which isn't normally available in the UI. ;)

    But you're right about total mass -- and I guess it's on Keen to fix, because the mass reported in the UI is not the true mass used for physics calculations. This is probably fine for UI-type scripts, but for scripts that want to apply F=ma, they will probably have to discern the inventory multiplier somehow (looking at cargo volumes was something I saw mentioned) and then massage the TotalMass value to get the "true" mass back, i.e.

    BaseMass + (TotalMass - BaseMass) / multiplier

    (TotalMass includes the mass of the pilot as well, apparently, but is probably negligible compared to the ship/cargo.)

    Anyway, I'm grateful that more information is now available. Last night, I was able to rip out all the velocity-related code from my scripts and replace it with IMyShipController.LinearVelocity. But I had to stop short at my scripts for player made weapons -- because they don't normally have a ship controller of any kind.
     
  9. Malware

    Malware Master Engineer

    Messages:
    9,867
    Sure, but I don't feel providing that information breaks those rules - which is why I included it.
     
  10. Wicorel

    Wicorel Senior Engineer

    Messages:
    1,263
    Palm up or down?
     
  11. plaYer2k

    plaYer2k Master Engineer

    Messages:
    3,160
    Right-hand coordinate system
    [​IMG]

    And i personally prefer configuration 1 the most. It is the easiest and most logical imo. Thumb = +x, index finger = +y, middle finger / palm normal = +z.

    That way you get the SE coordinates easy too with holding your right hand in front of you so that you look straight at the palm, the thumb goes to the right and the index finger straight up. Because we know in SE: +x = right, +y = up, +z = back.
     
    • Informative Informative x 1
  12. Seamus Donohue

    Seamus Donohue Trainee Engineer

    Messages:
    90
    Code:
    /* This program tests the new structures exposed in IMyShipController on Thursday, May 19, 2016.
       Space Engineers version 01.135.004 
    
       The exposed variables are courtesy of Lord Devious, a.k.a. Malware.
       
       This program written by Seamus Donohue of EVE University, Saturady, May 21st, 2016.
    
       To use this program, set up a Timer Block set to Trigger Now on itself and run this program. */
     
    string outputblockstring = "Text Panel 1";
    string remotecontrolstring = "Remote Control 1";
     
    void Main(string argument) { 
        IMyTerminalBlock rcblock = GridTerminalSystem.GetBlockWithName(remotecontrolstring);
        IMyTextPanel output = (IMyTextPanel)GridTerminalSystem.GetBlockWithName(outputblockstring); 
     
        if (rcblock == null) throw new Exception("\n\nRemote Control not found by name, check string constants."); 
        if (output == null) throw new Exception("\n\nText Panel not found by name, check string constants."); 
     
        IMyShipController rc = (IMyShipController)rcblock;
     
        Vector3D rcposition = rc.GetPosition();
    
        MyShipVelocities velocitystats = rc.GetShipVelocities();
        MyShipMass massstats = rc.CalculateShipMass();
    
        int shipmass = massstats.BaseMass;
        int totalmass = massstats.TotalMass;
        Vector3D velocity = velocitystats.LinearVelocity;
        Vector3D rotation = velocitystats.AngularVelocity;
     
        output.WritePublicText("Position:\n" + rcposition.X + "\n" + rcposition.Y + "\n" + rcposition.Z + "\n"
                             + "\nshipmass:" + shipmass + "\ntotalmass:" + totalmass
                             + "\ncargo:" + (totalmass-shipmass)
                             + "\nLinVel:\n" + velocity.X + "\n" + velocity.Y + "\n" + velocity.Z + "\n"
                             + "\nAngVel:\n" + rotation.X + "\n" + rotation.Y + "\n" + rotation.Z + "\n");
    }
    The above code works, provided that the necessary blocks are present.

    Angular Velocities are in terms of world axes, not ship axes. Angular Velocities are right-handed. So, if you're in a ship facing the world coordinates GPS:+Y:0:1000000000:0: , rolling right (clockwise) gives a positive value to the Y component of the Angular Velocity.

    Some oddities with the mass. "totalmass", as above, seems to always be 100 kg more than the mass shown in the HUD while I'm in a Cockpit. (Presumably, my astronaut has a mass of 100 kg, including suit.) "totalmass" also does not seem to take into account any items in the Cockpit or in any player inventory.
     
  13. mze9412

    mze9412 Junior Engineer

    Messages:
    791
    Cockpit inventory is a strange thing right now. It is the only inventory block not implementing IMyInventoryOwner but calling the HasInventory method only works on blocks which implement IMyInventoryOwner because it casts internally to IMyInventoryOwner. The inventory methods are all on IMyTerminalBlock now but IMyInventoryOwner is still necessary but it is deprecated.

    Thanks for the test code!!!
     
  14. Malware

    Malware Master Engineer

    Messages:
    9,867
    The oddities about the mass is beyond the scope of my work. You're gonna have to report that to Keen :)One thing that is strange is that you see a difference. There shouldn't be, I'm using the exact same code that the HUD does... :stare:

    I kinda expected the angular velocities to be in terms of world axes. However... I'm torn on whether this is actually wrong or not, when one takes the linear velocity into account. If one of them is to be changed to local, both should be.
     
  15. mexmer

    mexmer Senior Engineer

    Messages:
    1,977
  16. Seamus Donohue

    Seamus Donohue Trainee Engineer

    Messages:
    90
    [​IMG]

    ...

    The linear velocity as reported is the linear velocity of the ship relative to the world origin and expressed along world axes. So, the linear and angular velocities are consistent, here.

    If we're going to talk about ship velocity in any other terms, then we need to be careful. The other vector of interest is ship velocity relative to the world, but expressed along ship axes. If you make the mistake of transforming ship velocity completely to a ship-based frame of reference, then you're going to get the result that ship velocity is zero, because the ship has zero velocity relative to itself.

    ...

    Oh, I forgot to ask, how computationally expensive is it to query CalculateShipMass() ? If I call that 60 times a second on a Dedicated Server, is that going to murder the server's framerate?
     
  17. plaYer2k

    plaYer2k Master Engineer

    Messages:
    3,160
    Decide youself :p

    Code:
    // Sandbox.Game.Entities.MyShipController
    public MyShipMass CalculateShipMass()
    {
    	int mass;
    	int currentMass = base.CubeGrid.GetCurrentMass(out mass, this.Pilot);
    	return new MyShipMass(mass, currentMass);
    }
    
    
    // Sandbox.Game.Entities.MyCubeGrid
    public int GetCurrentMass(out int baseMass, MyCharacter pilot = null)
    {
    	baseMass = 0;
    	int num = 0;
    	MyGroups<MyCubeGrid, MyGridPhysicalGroupData>.Group group = MyCubeGridGroups.Static.Physical.GetGroup(this);
    	if (group != null)
    	{
    		foreach (MyGroups<MyCubeGrid, MyGridPhysicalGroupData>.Node current in group.Nodes)
    		{
    			MyCubeGrid nodeData = current.NodeData;
    			if (nodeData != null && nodeData.Physics != null && nodeData.Physics.Shape != null)
    			{
    				HkMassProperties? massProperties = nodeData.Physics.Shape.MassProperties;
    				HkMassProperties? baseMassProperties = nodeData.Physics.Shape.BaseMassProperties;
    				if (!this.IsStatic && massProperties.HasValue && baseMassProperties.HasValue)
    				{
    					float mass = massProperties.Value.Mass;
    					float mass2 = baseMassProperties.Value.Mass;
    					float num2 = mass - mass2;
    					baseMass += (int)mass2;
    					num += (int)(mass2 + num2 * MySession.Static.Settings.InventorySizeMultiplier - ((pilot != null) ? pilot.BaseMass : 0f));
    				}
    			}
    		}
    	}
    	return num;
    }
    I would say "not too intensive" for most ships. Even some insane things like i do with over 6000 grids it shouldnt be too much of an issue.
     
  18. Malware

    Malware Master Engineer

    Messages:
    9,867
    Hence my hesitancy. The only other viable option would be speed relative to the world, but axis relative to the ship... which I think would only add to the confusion.

    Well, as @plaYer2k says (thanks by the way :) ) not too much - although I named it "calculate" rather than "get" on purpose.
     
    • Like Like x 1
  19. Innoble

    Innoble Apprentice Engineer

    Messages:
    238
    Just an idea (referring to the screenshots). I might be totally off here, but: I see a mass of 11254 kg and a mass of 11354 kg. Not sure if player characters have mass, but if they do, then 100 kg might be a pretty good estimate...
     
  20. w0lf3y

    w0lf3y Apprentice Engineer

    Messages:
    152
    when i saw this on the update video i was hopeful for altitude to have been included. But Kudos none the less Malware. more option and access is a lovely thing.
     
  21. Malware

    Malware Master Engineer

    Messages:
    9,867
    Yes, I... as embarassing as it is... forgot. I had all intention to do so but I bloody forgot. :(
     
    • Funny Funny x 3
  22. Ronin1973

    Ronin1973 Master Engineer

    Messages:
    4,964
    There, there, Mr. Devious. We are grateful for what we've received.

    If you can include it in a future update... say.... next week... we'd be right as rain.

    But siiiiiiiiince you're going in there anyways...

    There's a variable regarding the center of the planet. Could you expose that as well? The center can be calculated already from two measurements of the gravity vector. So it would just be saving a time consuming step to get at the information by having it available to query.

    Having the planet center makes circumnavigating the planet possible. It will also help with thrust calculations and possibly other scripting... such as terrain mapping.
     
  23. Malware

    Malware Master Engineer

    Messages:
    9,867
    Yes well... It's not as easy as it might seem getting stuff in there, so I can't promise anything.
     
  24. Wicorel

    Wicorel Senior Engineer

    Messages:
    1,263
    inventory multiplier would be another good one..
     
  25. Malware

    Malware Master Engineer

    Messages:
    9,867
    That is metainformation.
     
  26. mze9412

    mze9412 Junior Engineer

    Messages:
    791
    That info could easily be checked by accessing one inventory anyway because of the MaxVolume property, right? So I would advocate for adding it directly somewhere to avoid useless workarounds to access that information. :)
     
  27. Malware

    Malware Master Engineer

    Messages:
    9,867
    Checking the MaxVolume is not meta. Checking a multiplier is. In addition to that I'm fairly certain not many scripters will have need for such information, it seems very much like an edge case to me. I will not add any further metainformation. If someone else will, then it's up to Keen, but I firmly believe any metainformation should be left out of PB API and I will not move away from that conviction.
     
  28. mze9412

    mze9412 Junior Engineer

    Messages:
    791
    Understood :) To be honest you are right, not many people would actually need that information :D
     
  29. Wicorel

    Wicorel Senior Engineer

    Messages:
    1,263
    "not many" probably true.

    It's needed to calculate the "effective mass" to know how much thrust to use.

    It can be calculated by script if it assumes the base max cargo volume (for a container) and compares that against the reported max cargo volume.

    However, if the base max cargo volume changes, the calculation would be broken.
     
    • Agree Agree x 1
  30. Innoble

    Innoble Apprentice Engineer

    Messages:
    238
    Anything you can set up when making a world on a server and is public to every player when they join the server should be accessible imho. The inventory multiplier is actually a very useful thing to know. I have made quite a few scripts where the user of the PB script had to go in and change the multiplier in a static int to make the script work properly every time they set it up.

    Possibly this is avoidable now because we can directly access inventory mass, but still I think it should be accessible, just like welding speed and refining speed. Other things are more important though, like center of mass for a ship and such.

    In any case, great job so far Malware!
     
    • Agree Agree x 1
Thread Status:
This last post in this thread was made more than 31 days old.