Jump to content

1.1.2 Magic Smoke Industries Infernal Robotics 2.0.2


sirkut

Recommended Posts

I don't know of any way to make the joints themselves less wobbly. I know the IR peeps have looked at it a few times over many months and there doesn't seem to be a solution, it's a KSP/unity engine thing as I recall. Something about the servo having to use a type of joint whose properties are set at a level that is inaccessible to modders.

Link to comment
Share on other sites

I've rewritten my code to use the KOS API and it is much nicer to read, but I have a problem: There doesn't seem to be a way to disengage limits when using the API, so calls to :moveto() always result in "snapping" when the target position is approached at high accelerations  Example at end of post.

I fear that the moveto() function is setting the limit and then just moving towards it, so disabling the limit wouldn't be possible, meaning there isn't a way to avoid the snapping when using the API. 

I know high accelerations are "weird", but I don't think they should cause a problem. There's no problem when servos are starting to move, only when they are stopping. When decelerating to a limit, can't the speed of the servo calculated by the acceleration behaviour be clamped to a maximum no higher than the current speed? Maybe I should inform myself of the actual IR code. In any case, if there's no solution to be found then maybe an option to "disable" the acceleration behaviour for a servo via the API/tweakable if desired?
 

if acceleration = -1 {  // decelerating
   servoSpeed = max(calculateAcceleratedSpeed(), currentServoSpeed); 
}

Here's the code:

declare s is addons:ir:allservos[0].

declare ms is list(list(0, 1), list(90, 2), list(45, 1), list(-45, 2)).
declare i is 0.

set s:acceleration to 500.
set s:speed to 1.

until false {	
	if not s:ismoving {
		s:moveto(ms[i][0], ms[i][1]).
		set i to i + 1.
		if i = 3 { set i to 0. }
	}
}
	

 

 

Edited by allmhuran
Link to comment
Share on other sites

Interpolator that accounts for acceleration has an edge case when servo approaches target position. Its not my code, but I'll take a look. For now you can try lower acceleration.

Link to comment
Share on other sites

I hope a simple fix is as above.... ie, clamp the result of the declerated speed calculation to a maximum of the current speed (obv not for acceleration since that would clamp the speed to 0 and it would never accelerate!) 

Unfortunately I can't use a lower acceleration. I need the servo speeds to move from point A to point B in a known time T (because I'm trying to keep several servos in synch), which means I need to call moveto(B, abs(B - A) / T). If the servos have any appreciable acceleration or deceleration, then the calculation doesn't work. I could try to factor the acceleration and deceleration into the calculation but I expect this will be more work than KOS can do in one frame (especially since it introduces a dependency where the timing depends on the acceleration of the servo that will take the longest to accelerate/declerate, and... well it's just really complicated), which makes the point moot since the timing will be out if update ticks occur while the calculation is being done.

Edited by allmhuran
Link to comment
Share on other sites

11 minutes ago, allmhuran said:

I hope a simple fix is as above.... ie, clamp the result of the declerated speed calculation to a maximum of the current speed (obv not for acceleration since that would clamp the speed to 0 and it would never accelerate!) 

Unfortunately I can't use a lower acceleration. I need the servo speeds to move from point A to point B in a known time T (because I'm trying to keep several servos in synch), which means I need to call moveto(B, abs(B - A) / T). If the servos have any appreciable acceleration or deceleration, then the calculation doesn't work. I could try to factor the acceleration and deceleration into the calculation but I expect this will be more work than KOS can do in one frame (especially since it introduces a dependency where the timing depends on the acceleration of the servo that will take the longest to accelerate/declerate, and... well it's just really complicated), which makes the point moot since the timing will be out if update ticks occur while the calculation is being done.

There is also a problem of a Physics tick

https://github.com/MagicSmokeIndustries/InfernalRobotics/blob/develop/InfernalRobotics/InfernalRobotics/Command/Interpolator.cs#L133

As you see here there is plenty of clamping but i believe the problem is with this 10% overhead, which gets noticeable at you level of acceleration

Link to comment
Share on other sites

Aww crap. Those damn physics ticks.

Edit: Hang on, that's just the returning out of the tick for the interpolator itself... surely a return from interpolator's update() doesn't force a return from the whole IR update(), preventing any other IR operations from occurring during that physics tick.... Again, I should probably look at the code myself to see all of this. But yeah, I definitely need to be able to move multiple servos in one tick.

Edited by allmhuran
Link to comment
Share on other sites

Just now, allmhuran said:

Aww crap. Those damn physics ticks.

You see from the line I linked that @pellinor left a very generous margin for edge case - I can lower it and give you a custom dll to test out

Link to comment
Share on other sites

Yeah, it looks backwards. A higher acceleration should allow it to get closer to the limit before having to say "I'm probably going to cross the limit next frame, so just jump to the limit now". Ie, The better your brakes, the later you can hit them. But instead, a higher acceleration is causing it to jump to the limit earlier. 

Link to comment
Share on other sites

19 minutes ago, allmhuran said:

Yeah, it looks backwards. A higher acceleration should allow it to get closer to the limit before having to say "I'm probably going to cross the limit next frame, so just jump to the limit now". Ie, The better your brakes, the later you can hit them. But instead, a higher acceleration is causing it to jump to the limit earlier. 

Try this build (re-uploaded the new dll)

 

https://github.com/MagicSmokeIndustries/InfernalRobotics/releases/tag/0.21.5-pre

Link to comment
Share on other sites

Just now, allmhuran said:

Yep, that fixes it for arbitrarily large accelerations!

Great. If you come up with a better algo feel free post here or as a github issue.

Link to comment
Share on other sites

Let me show you how much that helps with servo synchronization. Here's three quick clips back to back. First the old code with 500 acceleration (lol), then the old code with 50 acceleration (wobbly because servos aren't synched), finally the new code with acceleration 2000 (smooooth).
 

 

Edited by allmhuran
Link to comment
Share on other sites

6 hours ago, allmhuran said:

Yeah I see the problem. It is being overly careful about overshooting. Erm, one sec, let me think on that for a moment.

In my understanding the underlying problem is that you are doing the interpolation yourself, and then the result is streamed to the IR interpolator which is told to come to a stop at each position.

I think a cleaner way to handle this would be to offer a mode that tries to keep its target speed until reaching the target position, assuming he will get new commands on the fly. It would only brake after overshooting, or when approaching a hard limit. This could actually work without the realtime requirement of getting new positions every physics tick.

Another way is to disable/bypass the interpolation entirely (i.e. write positions directly). This is more or less what happens when you set huge acceleration values. There might still be a bit of weirdness here and there because it was not an intended use case when I wrote the interpolation code.

Of course the silver bullet would be true synchronous interpolation, i.e. only one interpolator for a set of servos. You would give it a list of positions, then it would calculate its dynamics (maxSpeed/maxAcc) based on the distance and dynamics of the involved servos, and move them all in sync. This is pretty straightforward for basic linear motion, but can become a huge can of worms once you get nonlinear (e.g. change 'direction' without stopping).

Edit: one more remark to the braking code: when determining maxSpeed from the distance to the limit, we are working on a SQRT curve, close to zero where it has a vertical tangent. So the problem is badly conditioned and the code for the last tick was done more or less by trial and error.

Edited by pellinor
Link to comment
Share on other sites

6 minutes ago, pellinor said:

In my understanding the underlying problem is that you are doing the interpolation yourself, and then the result is streamed to the IR interpolator which is told to come to a stop at each position.

I think a cleaner way to handle this would be to offer a mode that tries to keep its target speed until reaching the target position, assuming he will get new commands on the fly. It would only brake after overshooting, or when approaching a hard limit. This could actually work without the realtime requirement of getting new positions every physics tick.

Another way is to disable/bypass the interpolation entirely (i.e. write positions directly). This is more or less what happens when you set huge acceleration values. There might still be a bit of weirdness here and there because it was not an intended use case when I wrote the interpolation code.

Of course the silver bullet would be true synchronous interpolation, i.e. only one interpolator for a set of servos. You would give it a list of positions, then it would calculate its dynamics (maxSpeed/maxAcc) based on the distance and dynamics of the involved servos, and move them all in sync. This is pretty straightforward for basic linear motion, but can become a huge can of worms once you get nonlinear (e.g. change 'direction' without stopping).

Hi, long time no see :) Here are the changes I made:

https://github.com/MagicSmokeIndustries/InfernalRobotics/pull/74/files#diff-e2ca92d8a9e6bebed32c75d95e97a475L133

I moved the edge case check after the newVel is calculated and performed the check against it versus raw maxDeltaVel, which was too high in @allmhuran's case

As for option to disable the acceleration completely - I'll see whether it is possible to untie interpolation easily.

Edited by Ziw
Link to comment
Share on other sites

15 minutes ago, Ziw said:

Hi, long time no see :) Here are the changes I made:

https://github.com/MagicSmokeIndustries/InfernalRobotics/pull/74/files#diff-e2ca92d8a9e6bebed32c75d95e97a475L133

I moved the edge case check after the newVel is calculated and performed the check against it versus raw maxDeltaVel, which was too high in @allmhuran's case

As for option to disable the acceleration completely - I'll see whether it is possible to untie interpolation easily.

 

Actually this is not an edge case but the end condition, i.e. the regular way of a servo to stop.

If maxDeltaVel was high, this means that the servo jumped to its commandPos in the old version. If the new version behaves differently, it does not consider the movement finished, and will be interrupted later by the next command. I guess this invalidates some of my considerations, in this case bypassing the interpolator will behave like the old version before your change.

Link to comment
Share on other sites

58 minutes ago, pellinor said:
58 minutes ago, pellinor said:

I think a cleaner way to handle this would be to offer a mode that tries to keep its target speed until reaching the target position, assuming he will get new commands on the fly. It would only brake after overshooting, or when approaching a hard limit. This could actually work without the realtime requirement of getting new positions every physics tick.

Another way is to disable/bypass the interpolation entirely (i.e. write positions directly). This is more or less what happens when you set huge acceleration values. There might still be a bit of weirdness here and there because it was not an intended use case when I wrote the interpolation code.

Of course the silver bullet would be true synchronous interpolation, i.e. only one interpolator for a set of servos. You would give it a list of positions, then it would calculate its dynamics (maxSpeed/maxAcc) based on the distance and dynamics of the involved servos, and move them all in sync. This is pretty straightforward for basic linear motion, but can become a huge can of worms once you get nonlinear (e.g. change 'direction' without stopping).

 

Yep, the non-linearity of the problem is what makes it very expensive to try to handle in kOS, hence the choice to turn in into a linear problem with a really high acceleration value - an unaccelerated mode, just as you've described.

For controlling the servos, my own algorithm takes a set of positions which it is going to cycle through. But before anything starts, I first create a smoothed set to use as the first argument for the move command: If the previous target, current target, and next target are all in order, I push the current target out to the next target. So, for example, an original set of positions {0, 20, 40, 50, 20, 30} is turned into {0, 40, 50, 50, 20, 30}, but the speed component still uses the orignal set. Ie, when moveto() is called, the speed is set so that the servo reaches the position of the original set in a specified time, but the servo "limit" itself is set out beyond that point, so that if it gets there a little "early" it is allowed to overshoot. In situations where it has to reverse, though, an overshoot is prevented. This can cause a slight jitter as a servo stops for a frame or two, but it's not too bad.

 

Link to comment
Share on other sites

Hello, I was wondering if there was a chance for a variable geometry hinge like in the original damned robotics (I think it was that pack) so that aircraft such as the b1 or f14 become more viable

Link to comment
Share on other sites

52 minutes ago, wjb55 said:

Hello, I was wondering if there was a chance for a variable geometry hinge like in the original damned robotics (I think it was that pack) so that aircraft such as the b1 or f14 become more viable

Welcome to the forum.

You can make a swept wing aircraft using the "Docking washer" from the main IR Pack found Here

What I did in this video was, use a Docking Washer on each wing (Assembled one at a time. Docking washer's don't work using symmetry). Then I also used Quantum Struts to secure the wings in either swept or forward positions.

 

Edited by V8jester
Link to comment
Share on other sites

I'm having a lot of trouble with the structural strength of these parts.  I wanted to make a crane that could load/unload a 3.75m Kontainer of heavy goods from a spaceplane to a mining base.  I counterweighted it with a big tank of water for ballast.  looked great in VAB.  When I launched it, all of the telescopic pistons just collapsed under the weight and the whole thing, plus the launchpad, just exploded.  The rotatrons also seem to have very weak structural strength.  I'm already using Kerbal Joint Reinforcement.  Is there any solution to this?  I need a *heavy* cargo crane, we're talking about moving 200t of cargo at a time here (3.75m Kontainers hold a lot!)

Link to comment
Share on other sites

7 hours ago, ss8913 said:

I'm having a lot of trouble with the structural strength of these parts.  I wanted to make a crane that could load/unload a 3.75m Kontainer of heavy goods from a spaceplane to a mining base.  I counterweighted it with a big tank of water for ballast.  looked great in VAB.  When I launched it, all of the telescopic pistons just collapsed under the weight and the whole thing, plus the launchpad, just exploded.  The rotatrons also seem to have very weak structural strength.  I'm already using Kerbal Joint Reinforcement.  Is there any solution to this?  I need a *heavy* cargo crane, we're talking about moving 200t of cargo at a time here (3.75m Kontainers hold a lot!)

Please try using Zodius reworked parts (linked multiple times here), they are reported to be a bit less wonky. Also you may want to scale up some parts, because original ones are not designed to hold such weights.

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...