Jump to content

[WIP] Unity Editor Plugin


VR_Dev

Recommended Posts

So I'm trying to get this project up and running again in 1.6. Unfortunately IR doesn't work in 1.6, so I have committed to switching to IR next. It looks like I can use the IR Wrapper in the same way (because kOS does), but it is failing with the error.

[LOG 19:40:32.595] 1/12/2019 7:40:32 PM,MemoryBridgeServer-IR3Wrapper,[IR3 Wrapper] Failed to grab Mechanism Type

If anyone has gotten the wrapper to work with IR next in 1.6 please let me know.

 

I'm still working on getting the plugin to work without IR so it could still be useful without robotics. @Stone Blue & @Hooligan Labs were curious about the workflow. Essentially you can use :

MemoryBridge.GetVector3();

MemoryBridge.SetVector3();

Get/SetFloat, Get/SetBool

to get and set any variable I have included in the API (Most of vessel and some other classes). If you want to send custom values, you need to compile a plugin that provides the variable you are looking for.

 

//Server side in a custom dll
Update()
{
	//Set a value to be read by Unity Client
    MemoryBridge.SetVector3("Custom String Name", Vessel.GetObtVelocity());

    //Get a value from Unity Client and apply it in game
	Vessel.FlightCTRLState.Roll = MemoryBridge.GetFloat("Custom Throttle String");
}

//Client side (Unity)
Update(){
	//Get the orbital velocity from KSP
    var orbitVel = MemoryBridge.GetVector3("Custom String Name");

	//Set throttle based on some custom code like a PID
	//You can test code here quickly without having to reload KSP each time
	MemoryBridge.SetFloat("Custom Throttle String", calculatedThrottle);
}

 

Edit and for anyone curious about my earlier post. I have my quadcopter autopilot at a pretty good place, which is why I'm returning to this project. Still needs a lot of PID tuning so if someone is good at that and has 70 bucks to buy a DJI Tello let me know.

 

 

Edited by VR_Dev
Link to comment
Share on other sites

7 hours ago, VR_Dev said:

Failed to grab Mechanism Type

Recently I saw this kind of error in few other forum threads on various mods. I was not reading in details what is related with this error and no longer recall threads where I readed about it.
I think it was from one mod that @linuxgurugamer maintain, but might be wrong. I apologize if I pinged linuxgurugamer without reason.

Link to comment
Share on other sites

4 hours ago, kcs123 said:

Recently I saw this kind of error in few other forum threads on various mods. I was not reading in details what is related with this error and no longer recall threads where I readed about it.
I think it was from one mod that @linuxgurugamer maintain, but might be wrong. I apologize if I pinged linuxgurugamer without reason.

That looks like an IR error, not anything else

Link to comment
Share on other sites

16 hours ago, kcs123 said:

Recently I saw this kind of error in few other forum threads on various mods. I was not reading in details what is related with this error and no longer recall threads where I readed about it.
I think it was from one mod that @linuxgurugamer maintain, but might be wrong. I apologize if I pinged linuxgurugamer without reason.

 

11 hours ago, linuxgurugamer said:

That looks like an IR error, not anything else


I appreciate the help but I actually got it to work by using the IRWrapper from the IR sequencer instead of from kOS. (Which may even be identical to the old one, not sure). When I left this project I was in the process of trying to rig any IR arm with IK, which I think is still possible, but pretty ambitious. First off I'm just going to get the hexapod up and running, then go from there.

There is a jerky-ness to the servos that wasn't there before, not sure if its an IR Next issue or something in my IK code.

 

Link to comment
Share on other sites

On 1/21/2019 at 5:42 PM, VR_Dev said:

Still needs a lot of PID tuning so if someone is good at that and has 70 bucks to buy a DJI Tello let me know.

Can't afford to buy drone and my PID tuning skills are not that good to be able to contribute in this. However, some time ago when I was looking to improve my kOS scripts, I found decent arduino AutoPID library. Some pieces of code might be worth to study.

Link to comment
Share on other sites

  • 2 weeks later...

Hey @VR_Dev, Cool to see you revisiting this!

I know you worked on your own walking algorithm and terrain adaptation in the past for this, but I don't suppose you're interested in exploring other options? I remember you saying previously that the bridge part was the thing that interested you most. The reason I ask is because I've recently been porting and updating some old walking code over to Unity to test out before porting to Arduino for my IRL Hexapod, and thought it could be good for KSP too.

I've actually been working on this code for the past 15 years in various forms and programming languages, with the first versions being scripts for walking units in the video game Total Annihilation. You can see gifs of two units from the game below. Incidentally these were taken by someone who's recreating the game engine, so used them to verify the script parser worked.

attachment.php?attachmentid=35374&stc=1&  attachment.php?attachmentid=35389&stc=1&
 

Then there was this attempt in C# + XNA I did 10 years ago:

Since then I've been rethinking the system and making notes but only in the last month have I had the urge to try the code. You can see various gifs below (forgive them in being tweets). Note that I am not interested in the inverse kinematics at this stage, but rather the trajectory planning of the leg target coordinates.

Also the big thing with this is that it's not specific to 6 legs. Here's a test I did with 10, but I don't think there's any real upper limit.

Hope to put this code up on github sometime this month.

Cheers!

Link to comment
Share on other sites

1 minute ago, Hooligan Labs said:

Wow, we now have people who do TA mods here? This thread just gets more awesome.

I don't do any more unfortunately, but back in the day I was involved in all sorts of things for the game! You can see some of the things on my old site, which is still live: http://id.tauniverse.com/

In fact my profile picture on here is the icon of a custom unit I made. A walker of course :P

CorECS-Game3.gif

Link to comment
Share on other sites

@ZodiusInfuser hey thanks for all the cool examples. The bridge works pretty well now so I actually came back to this project hoping to focus solely on making the hexapod as advanced as possible. Part of that being it's gait. Looking back on the old videos I'm actually amazed how fast I got this thing moving. I have rebuilt the gait system to be more reliable as well as built in a simple gait sequencer. You can now add target positions to a gait list and have the hexapod execute them. If the new position is in front of the current(relative to the vessel) the foot will arc to the new position. If the new position is behind the current, it will translate across  the ground. Pretty much exactly like the example you posted above.

groupLeft.limb0.AddGaitTarget(groupLeft.limb0.limbIK.pointBack);
groupLeft.limb0.AddGaitTarget(groupLeft.limb0.limbIK.pointFront);
groupLeft.limb0.RunGait();

The problem I am currently experiencing is having the foot explode on ground contact. I solved this in Gen 1 by using a PID controller to control the speed for each individual servo. By setting a high D value the servos would slow as they got to their target. A main difference between the old and new gait is that I now use lerp to move the target position, so the target position itself slows as it gets to its destination. I thought this would be even better than the old gait where the target moved with a constant speed, but that doesn't seem to be the case.

 

The problem here is the leg will switch from an arc to translate when the actual foot position gets within .1m of the target position. When that happens the foot is still above the ground, so it comes in slowly, the target changes, and it then slams into the ground. In translate mode I also adjust the gait y position to get the hip/base of the arm to the proper height. So as soon as the mode switches, the new target may be under the ground, which doesn't help with the exploding feet. I tried getting servo.HostPart.GroundPosition to know when the foot is actually on the ground, but it only returns false (I may be doing this wrong still, because I've gotten it to work before.)

I am now keeping the repo up to date so anyone can take a crack at adjusting my code or implementing your own. The repo has the code for the KSP plugin, the Unity project, the hexapod ship, and the GameData folder. You should only need IR next to make it work. 

Basically there is a RoboticController class. This has two groups of LegControllers. A LegController class contains both references to the RoboticLimbIK and RoboticLimbMirror classes, which control the Ik and KSP mirror leg. If you really want to take a crack at it let me know and i can explain in more detail. This is a project I do in what freetime I have, so the code could be cleaned up and streamlined(also some comments might help). Right now everything is basically in prototype form.

 

Link to comment
Share on other sites

Unfortunately, I'm not able to find your repo. Where is the link? :D

My guess is that you should control the foot "touchdown" by velocity. Each KSP part has a certain velocity impact which it can take, above that it explodes. Multiply that speed by a safety factor and it should be good.

I'm not sure where you are getting "servo.HostPart.GroundPosition", but in my experience these special APIs can be meant for a very specific purpose and eventually break as new KSP versions come out. Your target position looks good. If you need a better estimate of distance, I would recommend a simple Physics.Raycast in the direction of gravity (which moves because KSP is way more realistic than most games).

Here is some pseudocode of how I imagine the touchdown could work.

// This is only intended for right before the foot touches the ground, assuming the foot is travelling in the right direction. A dot product or angle comparison between the intended travel direction and actual travel direction may be good as a sanity check.

float V_max; // Fastest speed that we can safetly touch the ground
float V_min; // We can go faster than this
float V_now; // Current velocity magnitude of part. KSP's API or base Unity code should work equally well, since they are the same for physics in the immediate location.

if (V_now > V_min) { // Going faster than needed?
	if (V_now > V_max) return; // Speed is fine
    servoSlowDown(); // Too fast, apply torque in direction slowing the foot
} else { // Going way slower than needed
	servoSpeedUp(); // Increase speed that the foot is being lowered
}

A quick P control on the velocity may be enough to know how much extra torque to apply. If this results in jerky movement (especially in different gravities), I would recommend calculating the desired torque by calculating leg weight and by considering leg distance.

Link to comment
Share on other sites

That blowing legs on video does not look it was moving too fast. It is rather some strange reaction between part colider and ground colider. Might be a case that Squad changed something between KSP verions ? Have you tried using ordinary truss instead of air intakes ? IIRC, truss was having quite high impact speed tolerance.

Link to comment
Share on other sites

19 hours ago, VR_Dev said:

@ZodiusInfuser hey thanks for all the cool examples. The bridge works pretty well now so I actually came back to this project hoping to focus solely on making the hexapod as advanced as possible. Part of that being it's gait. Looking back on the old videos I'm actually amazed how fast I got this thing moving. I have rebuilt the gait system to be more reliable as well as built in a simple gait sequencer. You can now add target positions to a gait list and have the hexapod execute them. If the new position is in front of the current(relative to the vessel) the foot will arc to the new position. If the new position is behind the current, it will translate across  the ground. Pretty much exactly like the example you posted above.


groupLeft.limb0.AddGaitTarget(groupLeft.limb0.limbIK.pointBack);
groupLeft.limb0.AddGaitTarget(groupLeft.limb0.limbIK.pointFront);
groupLeft.limb0.RunGait();

 

Ah cool that you're developing your own gait sequencer, and it's interesting how different our approaches are.

In mine the gait sequencer is abstracted from physical coordinates, so rather than giving it positions I give it stride start and end times for a looping cycle. This allows me to compute a line/arc for each leg to follow, and scale the length and time-step of the gait accordingly, ensuring that all steps stay within the capsule outlines I define on the ground (can be circles too). So far this has worked pretty well, letting me change the user input on the fly (as my second tweet shows). Of course there is no physical or simulated robot yet so there may be factors I have yet to consider, so we'll have to see. Terrain adaptation works though, which is nice.

19 hours ago, VR_Dev said:

I am now keeping the repo up to date so anyone can take a crack at adjusting my code or implementing your own. The repo has the code for the KSP plugin, the Unity project, the hexapod ship, and the GameData folder. You should only need IR next to make it work. 

Basically there is a RoboticController class. This has two groups of LegControllers. A LegController class contains both references to the RoboticLimbIK and RoboticLimbMirror classes, which control the Ik and KSP mirror leg. If you really want to take a crack at it let me know and i can explain in more detail. This is a project I do in what freetime I have, so the code could be cleaned up and streamlined(also some comments might help). Right now everything is basically in prototype form.

Thanks for putting your code up! Once I have something of mine up I will take a look. I imagine much of your IK stuff will be very useful! What license you using?

Link to comment
Share on other sites

Quote

In mine the gait sequencer is abstracted from physical coordinates, so rather than giving it positions I give it stride start and end times for a looping cycle. 

@ZodiusInfuser I do like the graphical interface you have here, must help a lot for debugging paths. Is your code also available for us to look at? It would seem to me that this would make for a more rigid walking cycle, but maybe I just need to see how you did it.

It seems you two have a shared understanding of hexapod walking. Can you recommend where I can read up on the technical aspects?

And it looks like VR_Dev's code creates a PID controller from IR to walk?

 

Link to comment
Share on other sites

3 hours ago, Hooligan Labs said:

@ZodiusInfuser I do like the graphical interface you have here, must help a lot for debugging paths. Is your code also available for us to look at? It would seem to me that this would make for a more rigid walking cycle, but maybe I just need to see how you did it.

Oh yes, they're great for debugging! The actual calculations are all done relative to the body (sphere), so I then when move the body in world space the paths should be smooth with no sudden jumps or sliding.

Code isn't available yet, but I would like to get something out there this month. Actually, I am hoping it will lead to a more dynamic walk cycle with some legs taking multiple strides for every one of another leg, and the ability to change gait whilst walking. But we'll have to see.

3 hours ago, Hooligan Labs said:

It seems you two have a shared understanding of hexapod walking. Can you recommend where I can read up on the technical aspects?

My learning journey for hexapods was from the old Lynxmotion forums, back when I built my own IRL hexapod. They were a company that sold walker kits, with various people making code to get them moving. Here's one relevant webpage: http://www.lynxmotion.com/images/html/proj102.htm The general thing to know is that there's actually two separate problems to deal with, the Inverse Kinematics of calculating the joint angles needed to have the end point of the leg align to a target position, then moving those target positions in such a way that produces a smooth motion. Currently what I have shown only deals with the latter, whereas VR_Dev is exploring both.

Link to comment
Share on other sites

17 hours ago, ZodiusInfuser said:

My learning journey for hexapods was from the old Lynxmotion forums, back when I built my own IRL hexapod. They were a company that sold walker kits, with various people making code to get them moving. Here's one relevant webpage: http://www.lynxmotion.com/images/html/proj102.htm 

Any page that ends with controlling a robot with a Wiimote is a good page. :) It seems that you both are working on a 2 step gait system, where 3 sets of legs alternate stance-swing-stance-swing.

I followed a few links from this page and ended up at this page, which I feel has some well commented code on walking gaits (even if it's not obvious from the file name) https://github.com/KurtE/BBD_SSC32_PS2/blob/39cd7a77ea5bd72fa1afd03654c08ff82466f766/BBD_SSC32_PS2.ino

If this is what the hexapod community is used to then I could see something like Unity being a big help. That is a lot of intense C code, servo trickery and mental coordinate conversion without abstraction!

I do see the benefit of working on these hexapods. Good stability seems possible with gaits calculated by linear algebra. Is it correct that your systems are not "rigid" and without power the robot would collapse to the ground? If so, is all the dampening through PID, and that is enough for the robot to not visibly stagger or sway?

Hope to have time to look through more of the technical information soon.

Link to comment
Share on other sites

2 hours ago, Hooligan Labs said:

Any page that ends with controlling a robot with a Wiimote is a good page. :) It seems that you both are working on a 2 step gait system, where 3 sets of legs alternate stance-swing-stance-swing.

I believe that's what VR_Dev was doing, yes. What I've been showing is a 3 step gait, with 2 legs moving at a time, and I'm currently testing a 5 step gait on a 10 legged robot.

2 hours ago, Hooligan Labs said:

I followed a few links from this page and ended up at this page, which I feel has some well commented code on walking gaits (even if it's not obvious from the file name) https://github.com/KurtE/BBD_SSC32_PS2/blob/39cd7a77ea5bd72fa1afd03654c08ff82466f766/BBD_SSC32_PS2.ino

If this is what the hexapod community is used to then I could see something like Unity being a big help. That is a lot of intense C code, servo trickery and mental coordinate conversion without abstraction!

KurtE was basically the expert for hexapods back in the day, so it doesn't surprise me the code is well commented. That code file in particular is for an Arduino board variant called Botboarduino, so I imagine a lot of it is the way it is to get around the 16Mhz clock speed of the microcontroller, and lack of a floating point unit. It being C rather than C++ is likely because the Arduino IDE doesn't make it clear that many of these chips do actually support C++. This is why I personally use Visual Studio for programming all my Arduino projects.

2 hours ago, Hooligan Labs said:

I do see the benefit of working on these hexapods. Good stability seems possible with gaits calculated by linear algebra. Is it correct that your systems are not "rigid" and without power the robot would collapse to the ground? If so, is all the dampening through PID, and that is enough for the robot to not visibly stagger or sway?

Hope to have time to look through more of the technical information soon.

Hexapods, or rather any walker with more than 4 legs are what are called statically stable, meaning that if the control software were to lock up at any time, the robot would not fall over. You are right about my irl hexapod not being "rigid", and has comically collapsed due to loss of motor power before :P. (vid of hexapod here if you haven't seen it) For Infernal Robotics though, I believe those hold their position even if no power is provided. PID is not something I've explored yet on hardware, as all servos contain the Proportional part of PID, and don't typically let you read their angle to implement the other two parameters in software.

Will be interesting to hear what you find out :)

Link to comment
Share on other sites

I got some more time to go through @VR_Dev's repo. First, I'd like to say that the more I read, the more impressed I am. There is a lot of interesting code here just to glue together the robot, and the mirror it in KSP!

As for your motion, I think that the feet are meant to be lifted or placed by this bit of code.

            globalPoint.y = ground.position.y;
         


            if(limbIK.legMode == RoboticLimbIK.LegMode.Translate)
            {
                globalPoint.y -= baseOffset;
            }

I would expect to see more of a snapping motion between these y positions. However, in your video the graphics for targeted location moves smoothly. I think that's the red skeleton.

It appears that you are achieving this smooth appearing target motion with RunGait(). At the start of the step, the target is way up in the air and near the foot's starting position. But then it is lerped forward and down to the actual target point on the ground at a speed per second controlled by the factor "limbController.roboticController.walkSpeed". I'm not sure, but there may actually be 3 targets: One that is between the fully lifted foot position and the target position, and then another between the foot and it's immediate target.

My guess that the "slam" is being caused by the PID tuning, like VR_Dev mentioned some posts ago. I think the PID values are being set in test.unity as:

hipElvPID_P: 1.5
hipElvPID_I: 1
hipElvPID_D: 4

From my PID experience, these are VERY large values for I and D! It's not uncommon to zero out I and D and use P alone because of how much damage those values can do.

In my theory, here is what is happening:

  • P (proportional) value simply is factoring the distance from target to actual position. This relationship is linear. There is only a spike in output if there is a distance spike.
  • D (derivative)
  • I (integral) is infamous because it effectively sum of all error over time, which can be horribly unpredictable in practice. It is good for handling error that the other factors can't. For example, a rusty door that is not quite closed may not be handled by P (can't overcome the friction) or D (doesn't care about position). However, the I value would eventually accumulate enough error to increase the force enough to close the door.

I think this affects the walking gait like so:

  • At the start of a step, the target is instantly above the foot. This snaps up the P and D values. The foot snaps up in the air. Good behavior.
  • The target moves forward and down. P wants to cause overshoot, but the D factor helps prevent this, as a high closing rate = negative distance over time = a large negative value. Not bad behavior, but the I factor may be slowly increasing this whole time due to small errors between actual and target position.
  • Foot goes to final position. P is of course small as the foot is already very close to the target to trigger this action. However, D is large! An instant change in target is effectively infinite slope! Thus, looking at ControlVariable or PidController, which seems to be called in FixedUpdate of VesselControl, probably the resulting value is 0.05 * 4 / 0.01 = 20! The I factor might not react quickly, but it probably adds to the resulting "slam" and may cause the foot to wiggle once it does reach the ground.

Therefore, I have the following recommendations:

  • Replace the PID with a ease-down function when the foot reaches the ground, just for comfort. You could instead have different PID settings for each part of the walk.
  • Maybe even remove having the target snap to the final desired position.
  • Zero out the I value. At least reset its calculation when the foot is about to touch the ground, maybe even the whole time the foot is on the ground. Depends on what you want I to do.
  • Reduce the D value. You may also have to reduce the P value to prevent overshoot. If this reduces walking ability, then you can reduce the walking speed and increase the baseOffset height. Not a great solution but could help. I notice that the D value of the hip rotation is already 0. Because the problem is slamming, not swinging, maybe the rotation P and D could increase while the Elev P and D decrease.

A way to test this would be to output the calculated results of the P, I and D factors and see how much they influence your system. If you see that I and D are adding a lot of torque to your servos when the foot goes down then my theory may be correct.

Other notes:

Spoiler

In the LimbController (which I think runs on your Unity instance, not KSP) I see "CustomUpdate" where you are calculating ground clearance - looks like you are reading a value directly calculated from within KSP. This is also where you are checking for GroundContact. I could see the ground clearance value being weird. It may be measuring from somewhere inside the part (not the bottom) and it may be measuring to the terrain collider (Kerbin dirt) and not the platform that you are standing on (some collider in the object). However, watching your video, it seems the value is working as intended.

 

Link to comment
Share on other sites

Hey guys I really appreciate all the insight in this thread. This week has been super busy at work so I haven't had time to keep up with all the questions. Also haven't had much time to put into the hexapod, but I do have it looking more like its old self though. Just like the first time around tuning is equally as important as the walking algorithm itself. The major improvements came from shortening up the stride length, and not changing targets til the foot has ground contact (Calculated from raycast). Also adding some more weight. Next big project is to set the steering PID to adjust stride length to keep it walking in a straight line.

Even if you don't understand any of the code there is also lots of design options that could be testing for advantages/disadvantages. You can alter the design of the craft(including the legs) pretty substantially and the code will still work. I'm also in the process of making it easier to tune. In this video I have also added engines back into the feet. My plan is for this to fly as well, so the weight needs to be taken into account.

 

On 2/5/2019 at 7:55 AM, ZodiusInfuser said:

This allows me to compute a line/arc for each leg to follow, and scale the length and time-step of the gait accordingly, ensuring that all steps stay within the capsule outlines I define on the ground (can be circles too). So far this has worked pretty well, letting me change the user input on the fly (as my second tweet shows). Of course there is no physical or simulated robot yet so there may be factors I have yet to consider, so we'll have to see. Terrain adaptation works though, which is nice.

Thanks for putting your code up! Once I have something of mine up I will take a look. I imagine much of your IK stuff will be very useful! What license you using?

I definitely need to implement something with more control over the speed of the two strides. I go into this more below. Oh boy I don't think I have a license specified yet. Whichever the free to use one is.

On 2/5/2019 at 2:00 PM, Hooligan Labs said:

And it looks like VR_Dev's code creates a PID controller from IR to walk?

PID controllers are used to control the speed of each servo based on the error between the mirror (ksp servo) and IK servo. A PID is also used to adjust the stride length to keep it walking in a straight line(not implemented yet). I go into it further below.

On 2/5/2019 at 5:20 PM, ZodiusInfuser said:

The general thing to know is that there's actually two separate problems to deal with, the Inverse Kinematics of calculating the joint angles needed to have the end point of the leg align to a target position, then moving those target positions in such a way that produces a smooth motion. Currently what I have shown only deals with the latter, whereas VR_Dev is exploring both.

Yeah the IK is sound, now its time to dive into the gait improvements.

On 2/6/2019 at 3:27 PM, ZodiusInfuser said:

I believe that's what VR_Dev was doing, yes. What I've been showing is a 3 step gait, with 2 legs moving at a time, and I'm currently testing a 5 step gait on a 10 legged robot.

Yeah I have a two step gait, with 3 legs translating backwards while the other three arc forward to the target position.

23 hours ago, Hooligan Labs said:

As for your motion, I think that the feet are meant to be lifted or placed by this bit of code.


            globalPoint.y = ground.position.y;
         


            if(limbIK.legMode == RoboticLimbIK.LegMode.Translate)
            {
                globalPoint.y -= baseOffset;
            }

I would expect to see more of a snapping motion between these y positions. However, in your video the graphics for targeted location moves smoothly. I think that's the red skeleton.

It appears that you are achieving this smooth appearing target motion with RunGait(). At the start of the step, the target is way up in the air and near the foot's starting position. But then it is lerped forward and down to the actual target point on the ground at a speed per second controlled by the factor "limbController.roboticController.walkSpeed". I'm not sure, but there may actually be 3 targets: One that is between the fully lifted foot position and the target position, and then another between the foot and it's immediate target.

@Hooligan Labs thanks a lot for taking the time to look into my code, and type up such an in depth response. The stuff on the PID was exceptionally helpful. The code above actually adjusts the target IK point to get the base of the arm at the correct height. If the base is .5m below its target, the IK target gets placed .5m below the ground, so the arm will push itself up trying to get to the below ground target. You can see in some of my old videos how I can control the height and angle of the body by adjusting these base targets. You can see here I was only doing that when the foot was translating across the ground, but now it will adjust its height when it is at its target position as well. Part of the snapping problem is when the target snapped from 0m above the ground to -.5m below the ground. It would probably be better to lerp this as well.

If you are referring to the box that is above the start position of the foot, that is left over from trying to use a target for the arc rotation. Now I just use a unity cheat to move the target in an arc. I just set the parent of the target at 0, and the target at the back or front position. The I lerp the parents rotation (factoring in walk speed) to get a nice arc that naturally slows as its nearing its target. The built in slow down of lerp doesn't seem to slow the foot enough however. I think the next step is to control the speed of the arc manually so that i can adjust when and by how much it slows as it gets closer to its target. This gets into what @ZodiusInfuser was saying about the time step. Right now I just try to manually adjust the speed of the rotation and translate so that the two groups of feet hit their target at the same time, but it would be much better to calculate the distance of both the straight line and arc, and set the speed accordingly, taking into account the slow down required on the rotation.

One other thought about the rotation target is to have the target be slightly above the ground. Then the arm does a full rotation really fast to get to that point, then gently set itself down.

23 hours ago, Hooligan Labs said:

My guess that the "slam" is being caused by the PID tuning, like VR_Dev mentioned some posts ago. I think the PID values are being set in test.unity as:


hipElvPID_P: 1.5
hipElvPID_I: 1
hipElvPID_D: 4

From my PID experience, these are VERY large values for I and D! It's not uncommon to zero out I and D and use P alone because of how much damage those values can do.

Pretty embarrassed I pushed those values up. I usually start with .1f,0,0 and move around from there. The high D was just and experiment to see if that would slow the arm enough to keep the foot from exploding. I still don't have a super clear understanding of PID tuning (your explanation def helps) but I don't think I'm half bad. My f-22 racers use a bunch of them.

23 hours ago, Hooligan Labs said:

I think this affects the walking gait like so:

  • At the start of a step, the target is instantly above the foot. This snaps up the P and D values. The foot snaps up in the air. Good behavior.
  • The target moves forward and down. P wants to cause overshoot, but the D factor helps prevent this, as a high closing rate = negative distance over time = a large negative value. Not bad behavior, but the I factor may be slowly increasing this whole time due to small errors between actual and target position.
  • Foot goes to final position. P is of course small as the foot is already very close to the target to trigger this action. However, D is large! An instant change in target is effectively infinite slope! Thus, looking at ControlVariable or PidController, which seems to be called in FixedUpdate of VesselControl, probably the resulting value is 0.05 * 4 / 0.01 = 20! The I factor might not react quickly, but it probably adds to the resulting "slam" and may cause the foot to wiggle once it does reach the ground.

Therefore, I have the following recommendations:

  • Replace the PID with a ease-down function when the foot reaches the ground, just for comfort. You could instead have different PID settings for each part of the walk.
  • Maybe even remove having the target snap to the final desired position.
  • Zero out the I value. At least reset its calculation when the foot is about to touch the ground, maybe even the whole time the foot is on the ground. Depends on what you want I to do.
  • Reduce the D value. You may also have to reduce the P value to prevent overshoot. If this reduces walking ability, then you can reduce the walking speed and increase the baseOffset height. Not a great solution but could help. I notice that the D value of the hip rotation is already 0. Because the problem is slamming, not swinging, maybe the rotation P and D could increase while the Elev P and D decrease.

So the PID loops are only controlling the speed of the servos, there is no PID that affects the gait (except for steering which shortens the gait as needed for turning. That isn't working in this version yet). Each servo has a PID which sets the speed according to the error between the mirror servo (KSP) and the IK leg servo. Mirror and IK arms are identical in the unity editor, the one lagging behind is always the mirror. I could just set the servo speed at max, but its nice to have the damping so it doesn't overshoot at the peak of the arc. The servos PID values should be different for the rotate and translate stride however. 

As I mentioned above, the gait probably has the most room for improvement, and I have a couple of different things to try. I'll definitely try out some of your suggestions.

23 hours ago, Hooligan Labs said:

In the LimbController (which I think runs on your Unity instance, not KSP) I see "CustomUpdate" where you are calculating ground clearance - looks like you are reading a value directly calculated from within KSP. This is also where you are checking for GroundContact. I could see the ground clearance value being weird. It may be measuring from somewhere inside the part (not the bottom) and it may be measuring to the terrain collider (Kerbin dirt) and not the platform that you are standing on (some collider in the object). However, watching your video, it seems the value is working as intended.

 

This is a problem I need to fix in the new System. If you watch the old videos, I used a sensor part to tell the system "this is the foot", and I shot a raycast straight down from that position to calculate ground clearance. The raycast ignored Parts and only looked for the layer that KSP considers the ground. In the new system I wanted the arm to calculate its endpoint automatically. So the wrist servo measures all the vertices in all the meshes attached to it, and uses the furthest Y distance to set the contact point.

This worked really well, except for sometimes that point clips below the ground mesh and the value is wrong. Now I use the same raycast, but from the servo transform. Then I set the ground(white plane) that distance below the identical servo in Unity. I calculate the clearance by subtracting the clearance from the servo to the foot position from the servo to the ground position. This works ok but is definitely worse, especially on a gradient. This def needs to be improved.

This is the api call that used to work as well. Not having any luck with it now though.

bool GroundContact

Whether this part is currently in contact with the solid surface of a CelestialBody.

Link to comment
Share on other sites

2 hours ago, VR_Dev said:

Next big project is to set the steering PID to adjust stride length to keep it walking in a straight line.

Looking forward to this. :)

Quote

Oh boy I don't think I have a license specified yet. Whichever the free to use one is.

I would recommend the MIT license then. It is what I used for all my mods. It simply protects the creator from liability. If you want to read more: https://opensource.org/licenses/MIT

Quote

@Hooligan Labs thanks a lot for taking the time to look into my code, and type up such an in depth response. The stuff on the PID was exceptionally helpful. 

Cool! I see that I understood some of it wrong though. If you post and update with some comments, I'd be happy to take another look.

Quote

Now I just use a unity cheat to move the target in an arc. I just set the parent of the target at 0, and the target at the back or front position. The I lerp the parents rotation (factoring in walk speed) to get a nice arc that naturally slows as its nearing its target.

That's not a cheat, that's smart. Unity has very good and fool-proof rotation, which should be taken advantage of!

Quote

One other thought about the rotation target is to have the target be slightly above the ground. Then the arm does a full rotation really fast to get to that point, then gently set itself down.

I'm not sure if I can recommend a specific solution. I just know that your feet should not hit the ground so fast they explode. Seems like a good control to have. :) 

Quote

Pretty embarrassed I pushed those values up. I usually start with .1f,0,0 and move around from there. The high D was just and experiment to see if that would slow the arm enough to keep the foot from exploding.

I think you worked against yourself by accident! Usually a high D does help reduce velocity, but if the target moves away rapidly then the D actually increases your pursuit speed.

Quote

So the wrist servo measures all the vertices in all the meshes attached to it, and uses the furthest Y distance to set the contact point.

I could see this being a little off. Also, I'm pretty sure KSP uses a few complex rotating reference frames so Y isn't guaranteed to be up. It is a little more computationally expensive, but I would recommend a raycast from every mesh point on the foot in the direction of gravity and use the smallest number. If that lags, perhaps do the raycast from the mesh point that has the largest dot product in the direction of gravity from the servo location. I think this is how you find the mesh's verticies at runtime: https://docs.unity3d.com/ScriptReference/MeshCollider-sharedMesh.html

By the way, you might still want to put feet at the end of your legs. I bet those engines have a rather small coefficient of friction. :) 

Link to comment
Share on other sites

  • 2 weeks later...

Hey, still working on this but having a lot of trouble with foot explosions. I now have KSP telling me when the foot explodes, so I can auto pause the unity controller and debug the values at the time of explosion. I have several new additions to the algorithm that seem promising, but I need to solve the foot explosions. I'm at the point I may just turn up the ground tolerance on the foot parts. Real life mechs wouldn't use delicate air intakes as their feet. 

Random assortment of thoughts and improvements I've made since my last post.

  • Foot explosions are really slowing me down. I assume the velocity used for ground collision is taken straight from RigidBody.velocity? I have been monitoring this on the foot, and even at the slow speed I'm walking it reaches velocities of 20+. (Explodes on contact > 7) My new thought is to use the velocity error to set the pids (when heading towards the ground) , but not sure how that would work. Again, may just turn up foot crash tolerance, I want to see how fast i can make this thing move, but need strong feet. Also tried turning acceleration down with little to no improvement.
  • I have changed the walking algorithm pretty dramatically. Used to wait for all 6 feet to be in position but now whenever the 3 arc-ing feet are in position at the front of the gate, the new cycle begins. The feet that are translating backwards across the ground have no target, they are lifted off the ground as soon as the other 3 feet are ready to begin translating, no matter where they are. This can cause problems if the translate speed is to slow, then it just takes these tiny steps. I need some kind of algorithm to set translate speed based on how far the other three legs have to arc.
  • In the video above the translate speed is fast enough that the legs are hitting their targets and stopping, ideally they would still be moving when its time to start the next cycle.
  • The gait targets are now asymmetrical. The front and back target used to be the same, half the stride length in each direction. but now the back point is further away from the center. The goal of this being the three feet that are translating should never stop(unless they are going to hit the let behind them), allowing for continuous motion.
  • I now lerp the position of the gait up and down to take into account legbase height. This offered a huge improvement.
  • Kind of abandoned servo PIDs, right now servo speed is just set to 20. I slow the IK target leg down when approaching the ground.
On 2/8/2019 at 2:49 PM, Hooligan Labs said:

Looking forward to this. :)

I would recommend the MIT license then. It is what I used for all my mods. It simply protects the creator from liability. If you want to read more: https://opensource.org/licenses/MIT

Video above has steering working, but not really featured. My old videos adjust to stay in a straight line, but now I can change the target direction to get the hexapod to turn. Thanks I'll update the repo with the license.

On 2/8/2019 at 2:49 PM, Hooligan Labs said:

I could see this being a little off. Also, I'm pretty sure KSP uses a few complex rotating reference frames so Y isn't guaranteed to be up. It is a little more computationally expensive, but I would recommend a raycast from every mesh point on the foot in the direction of gravity and use the smallest number. If that lags, perhaps do the raycast from the mesh point that has the largest dot product in the direction of gravity from the servo location. I think this is how you find the mesh's verticies at runtime: https://docs.unity3d.com/ScriptReference/MeshCollider-sharedMesh.html

I never use global Y, just the vessel's Y. That many raycasts would slow KSP way down. MeshColliders proved a global point to the closest given point, so I ask the collider what is the closest point to the planet, and now that's what I use. I also base all the calculations off that changing point, which gives better results. You can see the contact point drawn in game.

x0ND5m4.png

On 2/8/2019 at 2:49 PM, Hooligan Labs said:

By the way, you might still want to put feet at the end of your legs. I bet those engines have a rather small coefficient of friction. :) 

The engines were tucked away in the legs so the aero intake is still the only thing coming in contact with the ground. I removed a them and the top of the foot because i was having such a hard time with foot explosions.

On 2/18/2019 at 4:30 PM, ZodiusInfuser said:

Hey! I realise this isn't my thread, but just thought I'd show you my Unity walking sim progress since I last posted here.

 

This is great, thanks for posting. Even more complex with more legs. I hadn't even considered translating directly left or right, that would be an interesting thing to try. I need to turn in place first.

On 2/20/2019 at 6:33 AM, funkheld said:

where can you please download the hexapod?

Thank you.
greeting

https://github.com/carter-james89/KSP-Unity-Editor-Plugin/tree/master/Ships (You may need to download the whole repo then just pull the craft file out)

Unfortunately KOS isn't going to work out of the box, but you can use KOS to control servos. So this could be adapted if you really wanted.

Edited by VR_Dev
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...