Jump to content

[WIP] Infernal Robotics - Next


Rudolf Meier

Recommended Posts

On ‎03‎.‎04‎.‎2018 at 12:25 AM, IMrChrisI said:

Hello :). Could we get angle translators? Torque input and 1:1 output and one free moving telescope? It will be very helpfull in building machines :) .

Can you explain this a little bit more? What's the idea behind and... how should they work? Free moving telescope... Extendatron without motor? ... we haven't yet finished talking about free moving rotatrons and springs, dampers and things like that... could be an idea for extentions...

Link to comment
Share on other sites

I wasn't sure to put my forward my ideas or not but here it goes ...

1. Concerning joints  : it is possible to put multiple joints to a single part,  let unity simulate them as per usual and where "outer" joints are the only ones with part's attachment nodes ?

2. To build on previous  question : is it possible to make new IR have part configs that can let "aftermarket" users (such as @ZodiusInfuser ) write custom parts that have internally complex mechanics. Examples are helical motion drivers, spiral motion drivers,  gearboxes (with one or multiple outputs). Math equations describing such motions may need to go into custom DLL modules (part.cfg may be insufficient) which is loaded by "master DLL" IR itself.

3. Would removing a joint (using Destroy() on it's component) make part connection between IR parts make them as rigid as any other "normal" part ? Would parts translated/rotated with that joint stay at those positions after destroying joint ? This would be presented as "fix" or "freeze" function to player. IR constructs would be unusable until player "reactivates" them but would be much more strong/rigid (even KJR may be notified about state of those parts and do it's magic on them, or not). I see this as the only way to have them as rigid as possible (i dabbled myself in C# trying to make simple robotic parts and noticed joints are the only way to go). This would make possible to have IR constructs not wobble too much during surface transports or launches.

Link to comment
Share on other sites

3 minutes ago, fatcargo said:

1. Concerning joints  : it is possible to put multiple joints to a single part,  let unity simulate them as per usual and where "outer" joints are the only ones with part's attachment nodes ?

Today you have multiple joints between parts. IR for example uses in most cases 2, in some situations up to 4 between the parts (due to limitations of the joint in unity). KSP itself does use 1 or 3 joints between parts (depending on the size of the node) and with autostruts does add even more.

But those joints are all attached to an object. What you are talking about would need multiple objects. And here comes the problem: objects need a mass, otherwise the joints don't work. It is better in KSP 1.4.x (because of the new unity used), but still not that easy to get good results. It may be possible to build something like that, but in the end I think it won't be as stable as it is now.

8 minutes ago, fatcargo said:

2. To build on previous  question : is it possible to make new IR have part configs that can let "aftermarket" users (such as @ZodiusInfuser ) write custom parts that have internally complex mechanics. Examples are helical motion drivers, spiral motion drivers,  gearboxes (with one or multiple outputs). Math equations describing such motions may need to go into custom DLL modules (part.cfg may be insufficient) which is loaded by "master DLL" IR itself.

I doubt that you can get good results. I think you should do this by calculating it somewhere but not try to let unity simulate this. And then you simply build a part that gives you the same output... @ZodiusInfuser can tell you more about it. He is building wheels that fall into this category.

12 minutes ago, fatcargo said:

3. Would removing a joint (using Destroy() on it's component) make part connection between IR parts make them as rigid as any other "normal" part ? Would parts translated/rotated with that joint stay at those positions after destroying joint ? This would be presented as "fix" or "freeze" function to player. IR constructs would be unusable until player "reactivates" them but would be much more strong/rigid (even KJR may be notified about state of those parts and do it's magic on them, or not). I see this as the only way to have them as rigid as possible (i dabbled myself in C# trying to make simple robotic parts and noticed joints are the only way to go). This would make possible to have IR constructs not wobble too much during surface transports or launches.

No. Removing the joint disconnects the parts. You have to add an additional one or modify it to make it rigid (or stronger).

I was planing to build something like that (activate/deactivate joint lock) into KJR (the version I built... maybe it will get merged back, but I cannot say if and when... I'm still negotiating this). But what I can say: this is working with autostruts. If you lock an IR joint, autostrut is informed and can then build struts over this joint... if you then unlock the joint again, it removes those autostruts.

Another option would be to use IR-ActiveStruts... unfortunatelly I'm not yet ready. I'm currently rewriting the project completely. But it shouldn't take that long. This would offer a more visible option.

But after all I think the stability of the joints is already not that bad.

 

Link to comment
Share on other sites

Thanks for the useful info !

 

RE point 2 : i was thinking along the lines of having custom motion parts that do not require rewriting IR. That way alternate complex/unusual joint groups can be added.

Link to comment
Share on other sites

2 hours ago, Rudolf Meier said:

I was planing to build something like that (activate/deactivate joint lock) into KJR...

ok, I will add this now

Edit: it is in KJR and a new release is online (see first page for links) ... new IR release will support this, should be out soon, I'm changing little things (cleaning and moving IK code into own module) ... I expect this to be online tomorrow

Edited by Rudolf Meier
Link to comment
Share on other sites

19 hours ago, Rudolf Meier said:

I was planing to build something like that (activate/deactivate joint lock) into KJR

Coming late to party, but would be possible, at least with powered IR parts to unlock/lock KJR joints just before starting to move and after you start to move such part ?

With option in SPH/VAB right click menu to toggle such option if it is allowed to autolock for KJR or not. Meaning, if you have two poered IR parts attached to each other and some other craft parts when you start to move only one part other one would still be locked trough KJR if not powered and if you not have such option to toggle locking.

So, in such case if I have that new option to allow KJR autolock on one part and not allow to autolock on second part, when first part start to move trough commands, KJR would disable lockong and all parts should move as intended because second IR part is not affected to autolock at all. Of course, you will have to be careful in craft design for what parts to allow autolock and for what parts to not.

Another alternative could be to put lock/unlock in action groups, so you can choose what part to unlock or lock before starting to move IR parts and after finished with it.

In theory, it should help to build stronger crafts that have movable IR parts, but on the other hand it could be another kraken bait.

Link to comment
Share on other sites

1 hour ago, kcs123 said:

Coming late to party, but would be possible, at least with powered IR parts to unlock/lock KJR joints just before starting to move and after you start to move such part ?

...

Another alternative could be to put lock/unlock in action groups, so you can choose what part to unlock or lock before starting to move IR parts and after finished with it.

In theory, it should help to build stronger crafts that have movable IR parts, but on the other hand it could be another kraken bait.

KSPs autostruts do have such a functionality and you can see how they use it in the "klaw". My thoughts were, that I should take this as an example and do it similar. And this means, that the joint is reconfiguring the auto-strut and KJR configuration when locked/unlocked. It's quite some work that has to be done for this reconfiguration. So I don't think it's a good idea to do it based on motor movements. But based on lock-states of the joints, that's something I think we should do. At least that's what the new version of IR that I will upload later this evening is doing and that's what the new KJR I did build supports now.

Link to comment
Share on other sites

2 hours ago, Rudolf Meier said:

It's quite some work that has to be done for this reconfiguration. So I don't think it's a good idea to do it based on motor movements. But based on lock-states of the joints, that's something I think we should do. At least that's what the new version of IR that I will upload later this evening is doing and that's what the new KJR I did build supports now.

Well, you are the one who do all of hard work, so you are the one who knows what is plausible to do and what not. In such scenario having ability to lock/unlock joints trough action group would come handy.  Maybe some kOS scripts in combination of new kOS GUI and IR parts might provide more user friendly usage from this new feature.

Link to comment
Share on other sites

1 minute ago, kcs123 said:

... having ability to lock/unlock joints trough action group would come handy. Maybe some kOS scripts in combination of new kOS GUI and IR parts might provide more user friendly usage from this new feature.

I think there should be actions for that already... and if not, I can add them. I haven't tested those so far :) 

Link to comment
Share on other sites

I install your version of IR and it doesn't have give me to option to tweak scale the parts in VAB, but when i install tweak scale separately it allows me to alter the parts in VAB, however upon launch parts explode or when i try to move even the simplest of servos the game crashes? Any reason why tweakscale wouldn't show in first place or is it not yet enabled?

Link to comment
Share on other sites

4 minutes ago, specificplayer said:

I install your version of IR and it doesn't have give me to option to tweak scale the parts in VAB, but when i install tweak scale separately it allows me to alter the parts in VAB, however upon launch parts explode or when i try to move even the simplest of servos the game crashes? Any reason why tweakscale wouldn't show in first place or is it not yet enabled?

IR supports TweakScale, but it does not install it... you have to install it separately. And the explosions... this sounds as if you have installed KJR, but not the version I built, but an other one. You need the special version I made... (side note: I'm currently negotiating with the original KJR developer about a pull request on Github)

Link to comment
Share on other sites

7 hours ago, Rudolf Meier said:

... the new version of IR that I will upload later this evening ...

Sorry for the delay... I run into problems. The new auto-strut and KJR mode seems to have a problem with time warping (should not be a big one after all) but while investigating this I found a bigger one... the Rotatrons are destroyed when going into time warp. It must be a problem with axis and things like that... but I thought I have fixed it in the past. Anyway... I need to fix this first.

... the good news on the other side is, that all other functions I was working on are done and the code is almost fully cleaned up. I have now also included the collision functions.

And the ActiveStruts are also on a good level now... graphics / animation is done, linking also... now I only need to combine those two.

Edit: ok, it's clear now what the bug is... I didn't see this before... the auto-strut KJR problem is solved, but if you put multiple IR parts on top of each other, we get a problem in time warping... this could take some time to solve

 

Edited by Rudolf Meier
Link to comment
Share on other sites

Removing KJR fixed the exploding but i was still getting crashes, moved the IR mod over to my backup KSP and it worked, the only difference being older saves ( a few weeks old ) and it didnt crash when resizing? Now when trying to move each mod over individually to find the conflict they all worked fine... Then when i moved my new save over to the backup it stopped working. I the deleted the save and tried my backup again with just the mods and no save... it didnt work.

Gonna give up on my saves and start a new ksp, gonna redownload over night and see if it work and if my old save "infected" it, kinda annoying how it was working and now i cant get it back.

 

Thanks for your help and great work.

Link to comment
Share on other sites

7 hours ago, specificplayer said:

Removing KJR fixed the exploding but i was still getting crashes, moved the IR mod over to my backup KSP and it worked, the only difference being older saves ( a few weeks old ) and it didnt crash when resizing? Now when trying to move each mod over individually to find the conflict they all worked fine... Then when i moved my new save over to the backup it stopped working. I the deleted the save and tried my backup again with just the mods and no save... it didnt work.

Gonna give up on my saves and start a new ksp, gonna redownload over night and see if it work and if my old save "infected" it, kinda annoying how it was working and now i cant get it back.

 

Thanks for your help and great work.

are you loading new crafts? from vab or sph I guess? and they have problems then? ... that shouldn't happen... I cannot say if loading works always, because here I think we could still find some bugs/problems (and the bug I'm currently fixing is related to this... timewarp and loading). It's hard to find all combinations that can occur here... but still, it shouldn't happen

Link to comment
Share on other sites

Hi, 

I was wondering if there is anyway to stop the parts bending the further out they get / the more they are. I was trying to make an arm/crane on an older install and was hoping there would be some sort of way that the extenders can still go in and out but stay strong and not bend? I am using KJR.

Sorry if this has already been asked 1000x times but I'm just trying to find a conclusive answer.

Images:

https://imgur.com/a/YwAIR

Link to comment
Share on other sites

Hi.

I am very bad speak english and I have some difficulties for read all messages from that topic.

I use old version IR (from ckan) with legacy parts. And I install that last betta version too. As result - I have a two IR items in the VAB menu. First menu item have inside old legacy parts and I can config its all parameters. Second item have inside all "IR Next" parts and if I open it config window - that window is empty. I can use only right click menu for that parts.

I need uninstall old version IR or I can use both versions? Help please.

Edited by =V=Heromant
Link to comment
Share on other sites

11 hours ago, =V=Heromant said:

I use old version IR (from ckan) with legacy parts. And I install that last betta version too. As result - I have a two IR items in the VAB menu. First menu item have inside old legacy parts and I can config its all parameters. Second item have inside all "IR Next" parts and if I open it config window - that window is empty. I can use only right click menu for that parts.

I need uninstall old version IR or I can use both versions? Help please.

hi, no you can use the old IR and IR next at the same time. They don't affect each other. If the only part of a vessel is an IR next part, then the configuration window remains empty. Maybe that's the problem? (little but in the gui... but I wanted to change the gui a little bit anyway, that's why I didn't try to fix that for now)

 

5 hours ago, tbankstemp said:

I am having the same issue with the Gantry Rail in 1.4.2. I am also having things explode on load if there are multiple IR parts connected to each other. For instance, parts that one would make a robot arm with. Pistons, rotors,etc.

yes... Beta 3 seems to have some problems with translational joints (I guess)...

Link to comment
Share on other sites

16 minutes ago, Rudolf Meier said:

Patch 1 for Beta 3 is online... there was a problem with position calculation in translational joints. I also removed some unneeded calls... and the rails don't explode anymore.

That's awesome, thanks. Nice and quick too. I'll test out my big contraption in a few hours and report back.  Thanks man.

Link to comment
Share on other sites

Hey Rudolf, can you please add (back) the IRWrapper.cs attached below? Not sure if its used in many mods but for sure KOS uses it and i miss that integration. I changed the code of original IRWrapper.cs from MagicSmokeIndustries/InfernalRobotics to accomodate new namespace, property/class name changes and other crazy "refactorings" you did :wink:

I will admit I just tested it with rebuilt KOS, two expendatrons (to check groups ^^) and a single rotatron so far, but all KOS "suffixes" for IR worked great on those parts and I also did break in VS debugger to check and validated that everything seems to map nicely. Will do more testing tomorrow with more parts and let you know. Only thing is that in that form we'd have to also merge that changes to API clients code, but to avoid that you'd have to revert some of the refactorings you did in interfaces, to make it API compliant back. Anyway I also have a patch for KOS ready so assuming they will merge then KOS integration could work right away (currently using it in game).

I do realise that probably you have some "new&improved" way for integration in mind and new shiny API you want to throw in later- but in the meantime you could at least merge this, wont hurt right? Might please some folks i guess.

Also, yeah I could refactor it more instead of just quickly patching the holes, but thought better to give you rough version now before you merge some more stuff and conflict the s**t out of my changes ^^

Anyway, patch below, send me an email for more convenient form or just add me on github so that i can make PR and later refactor getting rid of duplicate type mappings etc:

Spoiler

diff --git InfernalRobotics/InfernalRobotics/API/IRWrapper.cs InfernalRobotics/InfernalRobotics/API/IRWrapper.cs
new file mode 100644
index 0000000..67799f0
--- /dev/null
+++ InfernalRobotics/InfernalRobotics/API/IRWrapper.cs
@@ -0,0 +1,752 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+
+namespace InfernalRobotics_v3
+{
+    public class IR3Wrapper
+    {
+        private static bool isWrapped;
+        private static bool? hasAssembly = null;
+
+        protected internal static Type IR3ServoControllerType { get; set; }
+        protected internal static Type IR3ControlGroupType { get; set; }
+        protected internal static Type IR3ServoType { get; set; }
+        protected internal static Type IR3ServoPartType { get; set; }
+        protected internal static Type IR3ServoMechanismType { get; set; }
+        protected internal static Type IR3ServoMotorType { get; set; }
+        protected internal static object ActualServoController { get; set; }
+
+        internal static IR3API IR3Controller { get; set; }
+        internal static bool AssemblyExists { get { return (IR3ServoControllerType != null); } }
+        internal static bool InstanceExists { get { return (IR3Controller != null); } }
+        internal static bool APIReady { get { return hasAssembly.HasValue && hasAssembly.Value && isWrapped && IR3Controller.Ready; } }
+
+        internal static Type GetType(string name)
+        {
+            Type type = null;
+            AssemblyLoader.loadedAssemblies.TypeOperation(t =>
+            {
+                if (t.FullName == name)
+                    type = t;
+            });
+            return type;
+        }
+
+        internal static bool InitWrapper()
+        {
+            // Prevent the init function from continuing to initialize if InfernalRobotics is not installed.
+            if (hasAssembly == null)
+            {
+                LogFormatted("Attempting to Grab IR3 Assembly...");
+                hasAssembly = AssemblyLoader.loadedAssemblies.Any(a => a.dllName.Equals("InfernalRobotics_v3"));
+                if (hasAssembly.Value)
+                    LogFormatted("Found IR3 Assembly!");
+                else
+                    LogFormatted("Did not find IR3 Assembly.");
+            }
+            if (!hasAssembly.Value)
+            {
+                isWrapped = false;
+                return isWrapped;
+            }
+
+            isWrapped = false;
+            ActualServoController = null;
+            IR3Controller = null;
+            LogFormatted("Attempting to Grab IR3 Types...");
+
+            IR3ServoControllerType = GetType("InfernalRobotics_v3.Command.Controller");
+
+            if (IR3ServoControllerType == null)
+            {
+                return false;
+            }
+
+            LogFormatted("IR3 Version:{0}", IR3ServoControllerType.Assembly.GetName().Version.ToString());
+
+            IR3ServoMechanismType = GetType("InfernalRobotics_v3.Control.IServo");
+
+            if (IR3ServoMechanismType == null)
+            {
+                LogFormatted("[IR3 Wrapper] Failed to grab Mechanism Type");
+                return false;
+            }
+
+            IR3ServoMotorType = GetType("InfernalRobotics_v3.Control.IMotor");
+
+            if (IR3ServoMotorType == null)
+            {
+                LogFormatted("[IR3 Wrapper] Failed to grab ServoMotor Type");
+                return false;
+            }
+
+            IR3ServoType = GetType("InfernalRobotics_v3.Control.IServo");
+
+            if (IR3ServoType == null)
+            {
+                LogFormatted("[IR3 Wrapper] Failed to grab Servo Type");
+                return false;
+            }
+
+            IR3ServoPartType = GetType("InfernalRobotics_v3.Control.IServo");
+
+            if (IR3ServoType == null)
+            {
+                LogFormatted("[IR3 Wrapper] Failed to grab ServoPart Type");
+                return false;
+            }
+
+            IR3ControlGroupType = GetType("InfernalRobotics_v3.Command.ControlGroup");
+
+            if (IR3ControlGroupType == null)
+            {
+                var IR3assembly = AssemblyLoader.loadedAssemblies.FirstOrDefault(a => a.assembly.FullName.Contains("InfernalRobotics_v3"));
+                if (IR3assembly == null)
+                {
+                    LogFormatted("[IR3 Wrapper] cannot find InfernalRobotics_v3.dll");
+                    return false;
+                }
+                foreach (Type t in IR3assembly.assembly.GetExportedTypes())
+                {
+                    LogFormatted("[IR3 Wrapper] Exported type: " + t.FullName);
+                }
+
+                LogFormatted("[IR3 Wrapper] Failed to grab ControlGroup Type");
+                return false;
+            }
+
+            LogFormatted("Got Assembly Types, grabbing Instance");
+
+            try
+            {
+                var propertyInfo = IR3ServoControllerType.GetProperty("Instance", BindingFlags.Public | BindingFlags.Static);
+
+                if (propertyInfo == null)
+                    LogFormatted("[IR3 Wrapper] Cannot find Instance Property");
+                else
+                    ActualServoController = propertyInfo.GetValue(null, null);
+            }
+            catch (Exception e)
+            {
+                LogFormatted("No Instance found, " + e.Message);
+            }
+
+            if (ActualServoController == null)
+            {
+                LogFormatted("Failed grabbing Instance");
+                return false;
+            }
+
+            LogFormatted("Got Instance, Creating Wrapper Objects");
+            IR3Controller = new InfernalRoboticsAPI();
+            isWrapped = true;
+            return true;
+        }
+
+        #region Private Implementation
+
+        private class InfernalRoboticsAPI : IR3API
+        {
+            private PropertyInfo apiReady;
+            private object actualServoGroups;
+
+            public InfernalRoboticsAPI()
+            {
+                DetermineReady();
+                BuildServoGroups();
+            }
+
+            private void BuildServoGroups()
+            {
+                var servoGroupsField = IR3ServoControllerType.GetField("ServoGroups");
+                if (servoGroupsField == null)
+                    LogFormatted("Failed Getting ServoGroups fieldinfo");
+                else if (IR3Wrapper.ActualServoController == null)
+                {
+                    LogFormatted("ServoController Instance not found");
+                }
+                else
+                {
+                    actualServoGroups = servoGroupsField.GetValue(IR3Wrapper.ActualServoController);
+                }
+            }
+
+            private void DetermineReady()
+            {
+                LogFormatted("Getting APIReady Object");
+                apiReady = IR3ServoControllerType.GetProperty("APIReady", BindingFlags.Public | BindingFlags.Static);
+                LogFormatted("Success: " + (apiReady != null));
+            }
+
+            public bool Ready
+            {
+                get
+                {
+                    if (apiReady == null || actualServoGroups == null)
+                        return false;
+
+                    return (bool)apiReady.GetValue(null, null);
+                }
+            }
+
+            public IList<IControlGroup> ServoGroups
+            {
+                get
+                {
+                    BuildServoGroups();
+                    return ExtractServoGroups(actualServoGroups);
+                }
+            }
+
+            private IList<IControlGroup> ExtractServoGroups(object servoGroups)
+            {
+                var listToReturn = new List<IControlGroup>();
+
+                if (servoGroups == null)
+                    return listToReturn;
+
+                try
+                {
+                    //iterate each "value" in the dictionary
+                    foreach (var item in (IList)servoGroups)
+                    {
+                        listToReturn.Add(new IR3ControlGroup(item));
+                    }
+                }
+                catch (Exception ex)
+                {
+                    LogFormatted("Cannot list ServoGroups: {0}", ex.Message);
+                }
+                return listToReturn;
+            }
+        }
+
+        private class IR3ControlGroup : IControlGroup
+        {
+            private readonly object actualControlGroup;
+
+            private PropertyInfo nameProperty;
+            private PropertyInfo vesselProperty;
+            private PropertyInfo forwardKeyProperty;
+            private PropertyInfo expandedProperty;
+            private PropertyInfo speedProperty;
+            private PropertyInfo reverseKeyProperty;
+
+            private MethodInfo moveRightMethod;
+            private MethodInfo moveLeftMethod;
+            private MethodInfo moveCenterMethod;
+            private MethodInfo moveNextPresetMethod;
+            private MethodInfo movePrevPresetMethod;
+            private MethodInfo stopMethod;
+
+            public IR3ControlGroup(object cg)
+            {
+                actualControlGroup = cg;
+                FindProperties();
+                FindMethods();
+            }
+
+            private void FindProperties()
+            {
+                nameProperty = IR3ControlGroupType.GetProperty("Name");
+                vesselProperty = IR3ControlGroupType.GetProperty("Vessel");
+                forwardKeyProperty = IR3ControlGroupType.GetProperty("ForwardKey");
+                reverseKeyProperty = IR3ControlGroupType.GetProperty("ReverseKey");
+                speedProperty = IR3ControlGroupType.GetProperty("Speed");
+                expandedProperty = IR3ControlGroupType.GetProperty("Expanded");
+
+                var servosProperty = IR3ControlGroupType.GetProperty("Servos");
+                ActualServos = servosProperty.GetValue(actualControlGroup, null);
+            }
+
+            private void FindMethods()
+            {
+                moveRightMethod = IR3ControlGroupType.GetMethod("MoveRight", BindingFlags.Public | BindingFlags.Instance);
+                moveLeftMethod = IR3ControlGroupType.GetMethod("MoveLeft", BindingFlags.Public | BindingFlags.Instance);
+                moveCenterMethod = IR3ControlGroupType.GetMethod("MoveCenter", BindingFlags.Public | BindingFlags.Instance);
+                moveNextPresetMethod = IR3ControlGroupType.GetMethod("MoveNextPreset", BindingFlags.Public | BindingFlags.Instance);
+                movePrevPresetMethod = IR3ControlGroupType.GetMethod("MovePrevPreset", BindingFlags.Public | BindingFlags.Instance);
+                stopMethod = IR3ControlGroupType.GetMethod("Stop", BindingFlags.Public | BindingFlags.Instance);
+            }
+
+            public string Name
+            {
+                get { return (string)nameProperty.GetValue(actualControlGroup, null); }
+                set { nameProperty.SetValue(actualControlGroup, value, null); }
+            }
+
+            public Vessel Vessel
+            {
+                get { return vesselProperty != null ? (Vessel)vesselProperty.GetValue(actualControlGroup, null) : null; }
+            }
+
+            public string ForwardKey
+            {
+                get { return (string)forwardKeyProperty.GetValue(actualControlGroup, null); }
+                set { forwardKeyProperty.SetValue(actualControlGroup, value, null); }
+            }
+
+            public string ReverseKey
+            {
+                get { return (string)reverseKeyProperty.GetValue(actualControlGroup, null); }
+                set { reverseKeyProperty.SetValue(actualControlGroup, value, null); }
+            }
+
+            public float Speed
+            {
+                get { return (float)speedProperty.GetValue(actualControlGroup, null); }
+                set { speedProperty.SetValue(actualControlGroup, value, null); }
+            }
+
+            public bool Expanded
+            {
+                get { return (bool)expandedProperty.GetValue(actualControlGroup, null); }
+                set { expandedProperty.SetValue(actualControlGroup, value, null); }
+            }
+
+            private object ActualServos { get; set; }
+
+            public IList<IServo> Servos
+            {
+                get
+                {
+                    return ExtractServos(ActualServos);
+                }
+            }
+
+            public void MoveRight()
+            {
+                moveRightMethod.Invoke(actualControlGroup, new object[] { });
+            }
+
+            public void MoveLeft()
+            {
+                moveLeftMethod.Invoke(actualControlGroup, new object[] { });
+            }
+
+            public void MoveCenter()
+            {
+                moveCenterMethod.Invoke(actualControlGroup, new object[] { });
+            }
+
+            public void MoveNextPreset()
+            {
+                moveNextPresetMethod.Invoke(actualControlGroup, new object[] { });
+            }
+
+            public void MovePrevPreset()
+            {
+                movePrevPresetMethod.Invoke(actualControlGroup, new object[] { });
+            }
+
+            public void Stop()
+            {
+                stopMethod.Invoke(actualControlGroup, new object[] { });
+            }
+
+            private IList<IServo> ExtractServos(object actualServos)
+            {
+                var listToReturn = new List<IServo>();
+
+                if (actualServos == null)
+                    return listToReturn;
+
+                try
+                {
+                    //iterate each key in the dictionary
+                    foreach (var item in ((IList)actualServos))
+                    {
+                        listToReturn.Add(new IR3Servo(item));
+                    }
+                }
+                catch (Exception ex)
+                {
+                    LogFormatted("Error extracting from actualServos: {0}", ex.Message);
+                }
+                return listToReturn;
+            }
+
+            public bool Equals(IControlGroup other)
+            {
+                var controlGroup = other as IR3ControlGroup;
+                return controlGroup != null && Equals(controlGroup);
+            }
+        }
+
+        public class IR3Servo : IServo
+        {
+            private object actualServoMotor;
+
+            private PropertyInfo maxConfigPositionProperty;
+            private PropertyInfo minPositionProperty;
+            private PropertyInfo maxPositionProperty;
+            private PropertyInfo configSpeedProperty;
+            private PropertyInfo speedProperty;
+            private PropertyInfo currentSpeedProperty;
+            private PropertyInfo accelerationProperty;
+            private PropertyInfo isMovingProperty;
+            private PropertyInfo isFreeMovingProperty;
+            private PropertyInfo isLockedProperty;
+            private PropertyInfo isAxisInvertedProperty;
+            private PropertyInfo nameProperty;
+            private PropertyInfo highlightProperty;
+            private PropertyInfo positionProperty;
+            private PropertyInfo minConfigPositionProperty;
+
+            private PropertyInfo UIDProperty;
+            private PropertyInfo HostPartProperty;
+
+            private MethodInfo moveRightMethod;
+            private MethodInfo moveLeftMethod;
+            private MethodInfo moveCenterMethod;
+            private MethodInfo moveNextPresetMethod;
+            private MethodInfo movePrevPresetMethod;
+            private MethodInfo moveToMethod;
+            private MethodInfo stopMethod;
+
+            public IR3Servo(object s)
+            {
+                actualServo = s;
+
+                FindProperties();
+                FindMethods();
+            }
+
+            private void FindProperties()
+            {
+                nameProperty = IR3ServoPartType.GetProperty("Name");
+                highlightProperty = IR3ServoPartType.GetProperty("Highlight");
+                UIDProperty = IR3ServoPartType.GetProperty("UID");
+                HostPartProperty = IR3ServoPartType.GetProperty("HostPart");
+
+                var motorProperty = IR3ServoType.GetProperty("Motor");
+                actualServoMotor = motorProperty.GetValue(actualServo, null);
+
+                positionProperty = IR3ServoMechanismType.GetProperty("Position");
+                minPositionProperty = IR3ServoMechanismType.GetProperty("MinPositionLimit");
+                maxPositionProperty = IR3ServoMechanismType.GetProperty("MaxPositionLimit");
+
+                minConfigPositionProperty = IR3ServoMechanismType.GetProperty("MinPosition");
+                maxConfigPositionProperty = IR3ServoMechanismType.GetProperty("MaxPosition");
+
+                isMovingProperty = IR3ServoMechanismType.GetProperty("IsMoving");
+                isFreeMovingProperty = IR3ServoMechanismType.GetProperty("IsFreeMoving");
+                isLockedProperty = IR3ServoMechanismType.GetProperty("IsLocked");
+
+                speedProperty = IR3ServoMotorType.GetProperty("SpeedLimit");
+                configSpeedProperty = IR3ServoMotorType.GetProperty("DefaultSpeed");
+                currentSpeedProperty = IR3ServoMotorType.GetProperty("Speed");
+                accelerationProperty = IR3ServoMotorType.GetProperty("AccelerationLimit");
+                isAxisInvertedProperty = IR3ServoMotorType.GetProperty("IsAxisInverted");
+            }
+
+            private void FindMethods()
+            {
+                moveRightMethod = IR3ServoMotorType.GetMethod("MoveRight", BindingFlags.Public | BindingFlags.Instance);
+                moveLeftMethod = IR3ServoMotorType.GetMethod("MoveLeft", BindingFlags.Public | BindingFlags.Instance);
+                moveCenterMethod = IR3ServoMotorType.GetMethod("MoveCenter", BindingFlags.Public | BindingFlags.Instance);
+                moveNextPresetMethod = IR3ServoMotorType.GetMethod("MoveNextPreset", BindingFlags.Public | BindingFlags.Instance);
+                movePrevPresetMethod = IR3ServoMotorType.GetMethod("MovePrevPreset", BindingFlags.Public | BindingFlags.Instance);
+                stopMethod = IR3ServoMotorType.GetMethod("Stop", BindingFlags.Public | BindingFlags.Instance);
+                moveToMethod = IR3ServoMotorType.GetMethod("MoveTo", new[] { typeof(float), typeof(float) });
+            }
+
+            private readonly object actualServo;
+
+            public string Name
+            {
+                get { return (string)nameProperty.GetValue(actualServo, null); }
+                set { nameProperty.SetValue(actualServo, value, null); }
+            }
+
+            public uint UID
+            {
+                get { return (uint)UIDProperty.GetValue(actualServo, null); }
+            }
+
+            public Part HostPart
+            {
+                get { return (Part)HostPartProperty.GetValue(actualServo, null); }
+            }
+
+            public bool Highlight
+            {
+                //get { return (bool)HighlightProperty.GetValue(actualServo, null); }
+                set { highlightProperty.SetValue(actualServo, value, null); }
+            }
+
+            public float Position
+            {
+                get { return (float)positionProperty.GetValue(actualServo, null); }
+            }
+
+            public float MinConfigPosition
+            {
+                get { return (float)minConfigPositionProperty.GetValue(actualServo, null); }
+            }
+
+            public float MaxConfigPosition
+            {
+                get { return (float)maxConfigPositionProperty.GetValue(actualServo, null); }
+            }
+
+            public float MinPosition
+            {
+                get { return (float)minPositionProperty.GetValue(actualServo, null); }
+                set { minPositionProperty.SetValue(actualServo, value, null); }
+            }
+
+            public float MaxPosition
+            {
+                get { return (float)maxPositionProperty.GetValue(actualServo, null); }
+                set { maxPositionProperty.SetValue(actualServo, value, null); }
+            }
+
+            public float ConfigSpeed
+            {
+                get { return (float)configSpeedProperty.GetValue(actualServoMotor, null); }
+            }
+
+            public float Speed
+            {
+                get { return (float)speedProperty.GetValue(actualServoMotor, null); }
+                set { speedProperty.SetValue(actualServoMotor, value, null); }
+            }
+
+            public float CurrentSpeed
+            {
+                get { return (float)currentSpeedProperty.GetValue(actualServoMotor, null); }
+                set { currentSpeedProperty.SetValue(actualServoMotor, value, null); }
+            }
+
+            public float Acceleration
+            {
+                get { return (float)accelerationProperty.GetValue(actualServoMotor, null); }
+                set { accelerationProperty.SetValue(actualServoMotor, value, null); }
+            }
+
+            public bool IsMoving
+            {
+                get { return (bool)isMovingProperty.GetValue(actualServo, null); }
+            }
+
+            public bool IsFreeMoving
+            {
+                get { return (bool)isFreeMovingProperty.GetValue(actualServo, null); }
+            }
+
+            public bool IsLocked
+            {
+                get { return (bool)isLockedProperty.GetValue(actualServo, null); }
+                set { isLockedProperty.SetValue(actualServo, value, null); }
+            }
+
+            public bool IsAxisInverted
+            {
+                get { return (bool)isAxisInvertedProperty.GetValue(actualServoMotor, null); }
+                set { isAxisInvertedProperty.SetValue(actualServoMotor, value, null); }
+            }
+
+            public void MoveRight()
+            {
+                moveRightMethod.Invoke(actualServoMotor, new object[] { });
+            }
+
+            public void MoveLeft()
+            {
+                moveLeftMethod.Invoke(actualServoMotor, new object[] { });
+            }
+
+            public void MoveCenter()
+            {
+                moveCenterMethod.Invoke(actualServoMotor, new object[] { });
+            }
+
+            public void MoveNextPreset()
+            {
+                moveNextPresetMethod.Invoke(actualServoMotor, new object[] { });
+            }
+
+            public void MovePrevPreset()
+            {
+                movePrevPresetMethod.Invoke(actualServoMotor, new object[] { });
+            }
+
+            public void MoveTo(float position, float speed)
+            {
+                moveToMethod.Invoke(actualServoMotor, new object[] { position, speed });
+            }
+
+            public void Stop()
+            {
+                stopMethod.Invoke(actualServoMotor, new object[] { });
+            }
+
+            public bool Equals(IServo other)
+            {
+                var servo = other as IR3Servo;
+                return servo != null && Equals(servo);
+            }
+
+            public override bool Equals(object o)
+            {
+                var servo = o as IR3Servo;
+                return servo != null && actualServo.Equals(servo.actualServo);
+            }
+
+            public override int GetHashCode()
+            {
+                return (actualServo != null ? actualServo.GetHashCode() : 0);
+            }
+
+            public static bool operator ==(IR3Servo left, IR3Servo right)
+            {
+                return Equals(left, right);
+            }
+
+            public static bool operator !=(IR3Servo left, IR3Servo right)
+            {
+                return !Equals(left, right);
+            }
+
+            protected bool Equals(IR3Servo other)
+            {
+                return Equals(actualServo, other.actualServo);
+            }
+        }
+
+        #endregion Private Implementation
+
+        #region API Contract
+
+        public interface IR3API
+        {
+            bool Ready { get; }
+
+            IList<IControlGroup> ServoGroups { get; }
+        }
+
+        public interface IControlGroup : IEquatable<IControlGroup>
+        {
+            string Name { get; set; }
+
+            //can only be used in Flight, null checking is mandatory
+            Vessel Vessel { get; }
+
+            string ForwardKey { get; set; }
+
+            string ReverseKey { get; set; }
+
+            float Speed { get; set; }
+
+            bool Expanded { get; set; }
+
+            IList<IServo> Servos { get; }
+
+            void MoveRight();
+
+            void MoveLeft();
+
+            void MoveCenter();
+
+            void MoveNextPreset();
+
+            void MovePrevPreset();
+
+            void Stop();
+        }
+
+        public interface IServo : IEquatable<IServo>
+        {
+            string Name { get; set; }
+
+            uint UID { get; }
+
+            Part HostPart { get; }
+
+            bool Highlight { set; }
+
+            float Position { get; }
+
+            float MinConfigPosition { get; }
+
+            float MaxConfigPosition { get; }
+
+            float MinPosition { get; set; }
+
+            float MaxPosition { get; set; }
+
+            float ConfigSpeed { get; }
+
+            float Speed { get; set; }
+
+            float CurrentSpeed { get; set; }
+
+            float Acceleration { get; set; }
+
+            bool IsMoving { get; }
+
+            bool IsFreeMoving { get; }
+
+            bool IsLocked { get; set; }
+
+            bool IsAxisInverted { get; set; }
+
+            void MoveRight();
+
+            void MoveLeft();
+
+            void MoveCenter();
+
+            void MoveNextPreset();
+
+            void MovePrevPreset();
+
+            void MoveTo(float position, float speed);
+
+            void Stop();
+
+            bool Equals(object o);
+
+            int GetHashCode();
+        }
+
+        #endregion API Contract
+
+        #region Logging Stuff
+
+        /// <summary>
+        /// Some Structured logging to the debug file - ONLY RUNS WHEN DLL COMPILED IN DEBUG MODE
+        /// </summary>
+        /// <param name="message">Text to be printed - can be formatted as per string.format</param>
+        /// <param name="strParams">Objects to feed into a string.format</param>
+        [System.Diagnostics.Conditional("DEBUG")]
+        internal static void LogFormatted_DebugOnly(string message, params object[] strParams)
+        {
+            LogFormatted(message, strParams);
+        }
+
+        /// <summary>
+        /// Some Structured logging to the debug file
+        /// </summary>
+        /// <param name="message">Text to be printed - can be formatted as per string.format</param>
+        /// <param name="strParams">Objects to feed into a string.format</param>
+        internal static void LogFormatted(string message, params object[] strParams)
+        {
+            var assemblyName = Assembly.GetExecutingAssembly().GetName().Name;
+            var declaringType = MethodBase.GetCurrentMethod().DeclaringType;
+            message = string.Format(message, strParams);
+
+            string strMessageLine = declaringType != null ?
+                string.Format("{0},{2}-{3},{1}", DateTime.Now, message, assemblyName, declaringType.Name) :
+                string.Format("{0},{2}-NO-DECLARE,{1}", DateTime.Now, message, assemblyName);
+
+            UnityEngine.Debug.Log(strMessageLine);
+        }
+
+        #endregion Logging Stuff
+    }
+}
 

 

Edited by mexorsu
clarification
Link to comment
Share on other sites

Ok, so I tested out some things and here are my findings.

*The below were the only parts I've tested*

Working:
Rails are good. :)
Extendatron - Basic and Half
Joint Pivotron - Basic and half

Not Working:
Rotatron - Basic
Rotatron - Uncontrolled
Joint Pivotron - Narrow angle
 

I assume it would be the same/similar issue as the Rails were. Same explodey thingy happens. I can provide logs and crash.dmp if needed.

Thanks.

Edited by tbankstemp
Hit post on accident.
Link to comment
Share on other sites

Gantry Rails, tested the patch and the craft doesn't explode, yeah! But trying to build a gantry craft with 1x Gantry Rail part moving north/south and another moving east/west it not working out that well. Gantry Rail moving east/west has no issue but then trying to move north/south cause the whole craft to move instead of the Gantry Rail part.

The other issue I have about the Gantry Rail part and some of the other parts, Rotatron parts. Why are the bottom attach nodes inverted? I change mine from: node_stack_center = 0.0, -0.05, 0.0, 0.0, 1.0, 0.0, 2 to node_stack_center = 0.0, -0.05, 0.0, 0.0, -1.0, 0.0, 2 this works great (can node attach top and bottom instead of surface attach) with the "original IR Gantry parts" for version 1.3.1 but if I try it in 1.4.2 with your Gantry parts we go back to exploding craft on launch.

Cheers

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...