Jump to content

[1.3] kOS Scriptable Autopilot System v1.1.3.0


erendrake

Recommended Posts

Right now, the script looks like this:

Please use [ code ] instead of a nested [ quote ] to embed your code examples. It works much better with "reply with quote" that way. Nested quoting doesn't work on this forum. Even when clicking the "multi quote" button it still won't do it.

I see one potential problem in that script:


if eng:ignition="true"

Eng:ignition returns a boolean. Comparing a boolean to a string is a bit of an unreliable result because of issues with case sensitivity (when eng:ignition is converted into a string for the sake of the comparison, does it use the value "TRUE" or "true" or "True"? It matters because string comparison is case sensitive).

A more reliable result is to just use the boolean as-is directly. Don't add the term ="true" when that's what using the bare boolean on its own already means anyway (and in fact is more reliable that way because of how boolean algebra works when the value isn't a boolean but is a plain number being treated like a boolean.)

A boolean value can be the entire expression, like so:


if eng:ignition // delete the = "true" part
{
.. do stuff ..
}

Link to comment
Share on other sites

Eng:ignition returns a boolean. Comparing a boolean to a string is a bit of an unreliable result because of issues with case sensitivity (when eng:ignition is converted into a string for the sake of the comparison, does it use the value "TRUE" or "true" or "True"? It matters because string comparison is case sensitive).]

Good point. Doubt it's causing the divide-by-zero/"tried to push infinity", though. The symptom of a bad boolean/"true" comparison would be a test returning false when the boolean is true, and the test has to be passing at least once for the thrust and isp lists to have nonzero length.

Link to comment
Share on other sites

This part of the script is actually designed as a staging condition.

The engines are indeed flamed out when the trigger is activated. The reason for this, is that when the <when>-body is triggered, there is virtually no fuel left. I`ll show you what I think why I get these error messages.

As for the boolean to string comparison:

I tried running the listscript without it being embedded in a <when>-body with activated engines. It returns the correct amount of isp. So I would think that this shouldn`t pose a problem. I´ll check again though.

I´ve tried relisting the engines in two different ways.

In this example I tried relisting the engine in the whenblock:


when stage:liquidfuel<0.001 then
{
clearscreen.
stage.
print "Staged!".

set x to 0.
set y to 0.
set isplist to list(). //list of engine isps
set thrlist to list(). //list of engine maxthrusts.
set thrtot to 0.
set thrisp to 0.

list engines in e.
for eng in e
{
if eng:ignition="true"
{
set isplist:add to eng:isp.
set thrlist:add to eng:maxthrust.
}.
}.

until thrlist:length=x
{
set thrtot to thrtot+thrlist[x].
set thrisp to thrisp+(thrlist[x]/isplist[x]).
set x to x+1.
}.

set isp to thrtot/thrisp.
print "Cummulative ISP: "+isp+" sec".
set t to 0.
wait 0.001.
preserve.
}.

With this configuration, I get an IPU error. Since I wanted to use this <when>-trigger for staging, I also tried manually staging the rocket with a throttle of 1 and then running the script.

As soon as the <when>-body triggered I get an IPU error again.

So I cranked up the config:IPU in order to test what would happen if there is enough IPU to go through the body. I got the errormessage described in my previous post.

The problem with this method, from what I can explain, is that when the <when>-body triggers, it creates a list based on the state of the ship at that exact moment (before staging). This means that the list will contain engines which are staged away a moment later.

The second problem is that the engines at that point in time are flamed out due to lack of fuel, which results in the isp of each engine being 0.

I can see that this could cause the infinity in stack error message.

In the second configuration, I set up 2 <when>-triggers:

The first <when> stages the rocket and sets a variable t to 1:


when stage:liquidfuel<0.001 then
{
clearscreen.
stage.
print "Staged!".
set t to 1.
wait 0.001.
preserve.
}.

That change to t triggers the other <when>-body with the list script:


when t=1 then
{
set x to 0.
set isplist to list().
set thrlist to list().
set thrtot to 0.
set thrisp to 0.
list engines in e.

for eng in e
{
if eng:ignition="true"
{
set isplist:add to eng:isp.
set thrlist:add to eng:maxthrust.
}.
}.

until thrlist:length=x
{
set thrtot to thrtot+thrlist[x].
set thrisp to thrisp+(thrlist[x]/isplist[x]).
set x to x+1.
}.

set isp to thrtot/thrisp.
print "Cummulative ISP: "+isp+" sec".
set t to 0.
wait 0.001.
preserve.
}.

I get the same error messages as above. Either too little IPUs or trying to push infinity into stack.

After looking over the second method, I realized that it does not help to trigger a <when> within a <when>-body. the timeframe in which both <when>-bodies are going through is the exact point in time before staging.

So what it boils down to is this:

I need a trigger which activates after a staging-event. This trigger may not be connected to the event itself. Does that make sense? It sure doesn´t to me :D.

I hope I could convey my problem without causing too much confusion. My brain hurts.

PS: Thank you for the tip with the boolean value. These are things I couldn´t find in the doc.

Link to comment
Share on other sites

Can KOS have specific launch times? Say I set it up so 3 rockets are on the pad and I want them in identical orbits but I want them launched 3 hours apart. Can I do this automatically with kOS?

Link to comment
Share on other sites

Can KOS have specific launch times? Say I set it up so 3 rockets are on the pad and I want them in identical orbits but I want them launched 3 hours apart. Can I do this automatically with kOS?

Yes, you can do math on the current time and arrange for something to run at a certain time in the future.

http://ksp-kos.github.io/KOS_DOC/structure/time/index.html

And also, can you have it follow a curve on the ascent?

Yes, you LOCK STEERING to a heading that's a function of your current velocity vector or altitude.

Link to comment
Share on other sites

Yes, you can do math on the current time and arrange for something to run at a certain time in the future.

http://ksp-kos.github.io/KOS_DOC/structure/time/index.html

But beware that kOS only actually runs correctly while the ship parts are loaded into the full game engine, not when the ship is *elsewhere* on rails. That makes it hard to both have kOS running the launch of one vessel and at the same time have the other vessels on the pad still running their kOS software to watch for timings.

Link to comment
Share on other sites

I need a trigger which activates after a staging-event. This trigger may not be connected to the event itself. Does that make sense? It sure doesn´t to me :D.

You have a few problems here happening at once:

1 - You are trying to do a wait in a trigger body. You can't. The Wait command is just ignored there. Therefore when the first trigger sets the flag "set t to 1." it might get seen by the second trigger during the *same* update, making the two triggers still run without giving the KSP game engine time to change the state of the ship in reaction to the stage command. (In a nutshell, you can't wait during a trigger because a trigger has to end entirely within one animation frame update, and the smallest possible granularity on a wait command is that it will wait at least 1 full animation frame.) A better test to give the behavior you're looking for is to check the current elapsed time TIME:SECONDS and record it during the first trigger and then have the second trigger wait for the condition where TIME:SECONDS is now a bit after it. Like so:


set trigTimeStamp to 0.
when stage:liquid fuel < 0.001 then
{
// do staging code here
set trigTimeStamp to TIME:SECONDS.
}
when trigTimeStamp > 0 and TIME:SECONDS > trigTimeStamp + 0.01 then
{
// do ISP code here.
}

That will ensure that at least one tick of game engine time has passed between the first trigger and the second, because during the same tick of game engine time, TIME:SECONDS will remain frozen at the same value.

2 - The trigger body must not contain much code because it needs to finish deterministically fast within one update. Adding loops to a trigger condition can be very dodgy for this reason. You aren't showing the main body of your program here - only the triggers. I suggest that you put the looping logic that's inside your ISP calculating trigger into the mainline code instead and have it get triggered by a flag each time the mainline code iterates a loop. Presumably your main code has a loop in it that is always going during the flight. Put the check there, and trigger it like so:


set trigTimeStamp to 0.
when stage:liquid fuel < 0.001 then
{
// do staging code here
set trigTimeStamp to TIME:SECONDS.
}

// main body of code presumably has a loop in it that always runs.
until something
{
if trigTimeStamp > 0 and TIME:SECONDS > trigTimeStamp + 0.01
{
set trigTimeStamp to 0. // turn this back off again so it won't happen twice.
// put all your ISP logic here instead of in the trigger.
}
else
{
// your normal flight control stuff here
}
}

Link to comment
Share on other sites

@foma87

Have you considered just moving the [wait 0.001] to between the [stage.] and [print "staged".]

Also unless you are using them for something else then you probably don't need to put the isp and thrust in their own lists.

You could try something like this to make the code shorter:

 FOR eng IN e {
IF eng:ignition {
SET thrtot to thrtot + eng:maxthrust.
SET thrisp to thrisp+(eng:maxthrust/eng:isp).
}.

Link to comment
Share on other sites

Have you considered just moving the [wait 0.001] to between the [stage.] and [print "staged".]

According to Steven, <wait> commands in triggerbodies have no effect, whom I like to thank for his insight on the <when>-mechanics.

Also unless you are using them for something else then you probably don't need to put the isp and thrust in their own lists.

You could try something like this to make the code shorter:

 FOR eng IN e {
IF eng:ignition {
SET thrtot to thrtot + eng:maxthrust.
SET thrisp to thrisp+(eng:maxthrust/eng:isp).
}.

I feel stupid now. This should actually give me the same results with less code. Nice find!

A better test to give the behavior you're looking for is to check the current elapsed time TIME:SECONDS and record it during the first trigger and then have the second trigger wait for the condition where TIME:SECONDS is now a bit after it. Like so:


set trigTimeStamp to 0.
when stage:liquid fuel < 0.001 then
{
// do staging code here
set trigTimeStamp to TIME:SECONDS.
}
when trigTimeStamp > 0 and TIME:SECONDS > trigTimeStamp + 0.01 then
{
// do ISP code here.
}

I´ve tried this exact idea yesterday, the error message persists however. As you explained, you`re right that the problem is running a loop in a <when>-body.

As for your suggestion with the timestamp and in the <until>-body, I think this might just do the trick! I`ll try it out and report back.

Much obliged.

Link to comment
Share on other sites

YES, I got it!

It actually worked with the timestamp in an <until>-body!!!

So now I got an orbiting script which is almost completely failsafe (when using rockets that is.). The only rule it has is no solid fuel boosters past the 1st stage.

When using only liquidengines it will run at fuel efficient throttle given the current height. When using a combination of solid and fuel engines, it will lock the throttle to lift the weight of the rocket without the solid boosters until those are empty. After that it switches to to fuel efficient throttle again.

It will start a gravity turn at 10k meters and end it at an angle of 45° at 32k meters.

And here comes the part with th ISP calculation:

The node for circularization is calculating the exact time the engines have to fire up in order to run through the node in the most efficient manner (half the burntime before the node, and half after). In order to do that, it needs to know the combined ISP of the currently ignited engines.

If the burntime of the node is greater than the leftover burntime of the current stage, it will jettison it, fire up the next stage, AND recalculate the combined ISP of the NOW currently ignited engines.

Thank you guys so much for your help!!!

And if anyone is interested (script is a whopping 3195 characters):


//lists

set hAsc to list().
set hAsc:add to 1000.
set hAsc:add to 10000.
set hAsc:add to 20000.
set hAsc:add to 32000.

set acUp to list().
set acUp:add to 6.05.
set acUp:add to 3.32.
set acUp:add to 22.04.
set acUp:add to 205.23.


//vAsc 110, 268, 716, 2332
//hAsc 1000, 10000, 20000, 32000
//aAsc 6.05, 3.32, 22.04, 205.23)


//script


//standard variables

set aAsca to 0.
lock v to verticalspeed.
lock h to altitude.
lock hApo to alt:apoapsis.
lock etaApo to eta:apoapsis.
set isp to 0.
set g0 to 9.81.
set aUp to 0.
lock thrMax to maxthrust.
lock mTot to ship:mass.
lock solFor to g0*(mTot-(stage:solidfuel*7.5)).
lock solAcc to solFor/thrMax.
lock liqFor to (g0+aAsca)*mTot.
lock liqUp to liqFor/thrMax.
set pitch to 0.
set dvNode to 0.
set t to 0.
set thrIsp to 0.001.
set thrTot to 0.001.


//staging, actiongroups, utilities, isp calculator

when stage:liquidfuel<0.001 and stage:solidfuel<0.001 then
{
unlock t.
clearscreen.
stage.
print "Staged!".
set t to time:seconds.
wait 0.001.
preserve.
}.

when stage:solidfuel<0.001 then
{
clearscreen.
stage.
print "Staged!".
}.

when h>70000 then
{
ag1 on.
panels on.
}.


//ascension

lock steering to up + R(0,0,180).

until hApo>125000
{
if stage:solidfuel>1
{
lock throttle to solacc.
}.

else

{
lock throttle to liqUp.

if h<hAsc[0]
{
set aAsca to acUp[0].
}.

if h<hAsc[1] and h>hAsc[0]
{
set aAsca to acUp[1].
}.

if h<hAsc[2] and h>hAsc[1]
{
set aAsca to acUp[2].
}.

if h<hAsc[3] and h>hAsc[2]
{
set aAsca to acUp[3].
}.
}.

if h>hAsc[1] and pitch>-45
{
set pitch to -((h-hAsc[1])/488.88).
lock steering to UP + R(0,0,180) + R(0,pitch,0).
}.
}.

lock throttle to 0.


//node variables and ispcalculator

list engines in e.

for eng in e
{
if eng:ignition="True"
{
set thrtot to thrtot + eng:maxthrust.
set thrisp to thrisp+(eng:maxthrust/eng:isp).
}.
}.

lock isp to thrtot/thrisp.
lock mDry to (mTot/(constant():e^(dvNode/(isp*g0)))).
lock fuelNeed to mTot-mDry.
lock fuelFlow to (thrMax/(isp*g0)).
set burnTime to (fuelNeed/fuelFlow).


//apoapsis node

set apoNode to node(time:seconds+etaApo, 0, 0, dvNode).
add apoNode.

until apoNode:orbit:periapsis>124000
{
set dvNode to dvNode+5.
remove apoNode.
set apoNode to node(time:seconds+eta:apoapsis, 0, 0, dvNode).
add apoNode.
wait 0.001.
}.

lock steering to apoNode.
wait 5.

if (stage:liquidfuel*5+stage:oxidizer*5)/1000<fuelNeed
{
unlock t.
stage.
set t to time:seconds.
}.

until apoNode:eta<((burntime/2)+60)
{
set warp to 3.
}.

set warp to 0.
wait 0.001.

until periapsis>120000
{
if t<time:seconds-1
{
set thrtot to 0.001.
set thrisp to 0.001.
list engines in e.

for eng in e
{
if eng:ignition="True"
{
set thrtot to thrtot + eng:maxthrust.
set thrisp to thrisp+(eng:maxthrust/eng:isp).
}.
}.
lock t to time:seconds.
set burnTime to (fuelNeed/fuelFlow).
}.

if apoNode:eta<(burntime/2) and dvNode>50
{
lock throttle to 1.
}.

if apoNode:eta<(burntime/2) and dvNode<50
{
lock throttle to 0.1.
}
}.

print "Done!".

edit: a little bug caused an error after staging a solidfuel booster. fixed hopefully.

edit: it seems like the max numer of engines you should use is 10.

Edited by foma87
Link to comment
Share on other sites

Is there a way to use kos to activate infernal robotics hot keys? I need to loop a sequence of servo movements.... currently I'm using an external script to do this, but the timing sometimes falls out sync and screws everything up.

Link to comment
Share on other sites

Is there a way to use kos to activate infernal robotics hot keys? I need to loop a sequence of servo movements.... currently I'm using an external script to do this, but the timing sometimes falls out sync and screws everything up.

There is what looks like a not-compiled possibly working prototype in the kOS Git-Hub, I was waiting patiently for something to happen but maybe if there's a few of us asking it could move up the to-do list. I've had the same trouble and integrating a "return to center" action group into each loop seems the only way at the moment.

Link to comment
Share on other sites

There is what looks like a not-compiled possibly working prototype in the kOS Git-Hub, I was waiting patiently for something to happen but maybe if there's a few of us asking it could move up the to-do list. I've had the same trouble and integrating a "return to center" action group into each loop seems the only way at the moment.

It's literally impossible for it to BE any higher on the TODO list than it *already* is.

It's debatable whether or not it's a good idea to announce publicly too much about the inner managing of a software project, as doing so often builds misunderstood anticipation hype in people's minds, but since people have been clamoring for this particular feature for a while now, and I've been talking it up, I figure I owe an explanation for the delay.

The reason there's been a delay is that the feature requires adding some language infrastructure underneath that kerboscript was missing, namely the ability to use suffix terms as function calls, like this for example:

SET FOO TO LIST().

FOO:ADD("val0").

FOO:ADD("val1").

FOO:ADD("val2").

FOO:ADD("val3").

FOO:ADD("val4").

print FOO:SUBLIST(1,2):LENGTH.

The work on the interface for reading part menu fields had to be halted until that underlying language feature was implemented first. Thankfully, as of late last night, I got the first potential experimental version of that language feature ready to merge in (but be warned it hasn't really been fully tested yet so there's a chance it can be found lacking and need more work).

Barring any further unforeseen problems with it, I expect to be back to working on the right click menu thing probably this weekend when I'll have all of Sunday free to spend "in the hacking zone" for it.

But again, be warned, that's *IF* something serious isn't found to be wrong with the suffix function call feature. I tested it fairly well myself but there may be use cases I hadn't thought of.

Long Version, for any computer programmers out there who can follow it:

Basically, we were missing the ability to pass arguments into the code that suffix terms run, which would allow them to behave like methods. Adding this required a major change to the grammar definition that shuffled the parse tree layout around. Anyone who's ever written parser code before knows that when you do that it has consequent effects on the code that percolate all down through the system so it's not a small task. It's the sort of change that breaks hundreds of assumptions all over the place that the code was silently making without those assumptions being documented. As the person who actually wrote the grammar parsing system in the first place no longer has free time for the project, this fell to me to do. Since I didn't know where all those secret assumptions were, many of them snuck up on me by surprise. Often a change would cause an error in a seemingly unrelated part of the system because the change violated an unstated assumption the code was making that I was unaware of, so it wasn't a quick thing getting it working.

Edited by Steven Mading
Link to comment
Share on other sites

Greetings all!

May someone ever so kindly cite simple examples of how to use Wheelsteering and WheelThrottle?

I have searched through this thread, the older thread, all of the reference material, the wiki, et all and am still in quite a desperate need of help. It appears to me that the usage of these has changed somewhat since the earlier days of kOS and this is perhaps why I am having such difficulty?

Anywho, I greatly ever so muchly with a cherry on top and a can of bananas to boot appreciate anyone who can tell me how this is done. I'd love to automate some of my rover processes and the like. :)

P.S. Long Time Lurker and this issue has officially led me to making my first post. I think kOS is worth it!

-Blake

Link to comment
Share on other sites

@InvertedBlack

Gaiiden has a rover script here http://forum.kerbalspaceprogram.com/threads/86177-kOS-12-2P3-Rover-Driver-pre-release .

If you want to just use lat & lon as way points (instead of game objects)i would suggest looking into great circle navigation. Which will give you a variable heading for the shortest path between 2 co-ordinates not essential but it helps when navigating near the poles.

Edit: Here is the equation for heading (tlat &tlon are target latitude and target longitude respectively)

LOCK heading TO ARCTAN2(SIN(tLon-SHIP:LONGITUDE)*COS(tLat),(COS(SHIP:LATITUDE)*SIN(tLat))-(SIN(SHIP:LATITUDE)*COS(tLat)*COS(tLon-SHIP:LONGITUDE))). 

great circle nav can also be used to find surface distance but i don't have the equation for that to hand.

Edited by TDW
Link to comment
Share on other sites

Hi, someone mentioned that Infernal Robotics is usable with kOS. I have a request if this is the case.

I was thinking that maybe a rotatron could be set to rotate a truss segment so that a certain side of it would face the sun when possible. Then, a pair of solar arrays could be attached top and bottom and thus they would get a full dose of the solar rays. Basically, how the ISS Solar arrays work.

Link to comment
Share on other sites

@falken

IR / generic right click menu support is being worked on (4 posts back :wink:) current support is via action groups and querying part facing.

Are you asking for help writing this or for someone to write it for you?

If its just a couple of pointers you want then here is how I would start out;

- First you need the truss part to be identifiable, with engines you can identify by stage but the truss would need a unique(to the vessel) part in it for this.

- Then the axis of rotation for the rotatron (should be the same as its facing, i think).

- The vector from you to the sun.

- Remove the axis of rotation component from the vector to the sun (vxcl).

- Use action group to rotate rotatron until the angle between the truss facing and the flattened of the sun vector approaches 0.

- If you want it more advanced then you can take the normal of the truss facing and rotatoron axis and if the angle between that and the flattened sun vector is >90 rotate 1 way and if it is < 90 rotate the other.

Edit:

The vector maths can be can here http://ksp-kos.github.io/KOS_DOC/structure/vector/index.html

Edit 2:

I forgot I came here to ask my own question :blush:.

Is there a way of forcing ROUND(var,2) to give decimal places even if there are none eg. 10.00 instead of 10? not a major thing just trying to neaten up a readout.

Edited by TDW
Link to comment
Share on other sites

Edit 2:

I forgot I came here to ask my own question :blush:.

Is there a way of forcing ROUND(var,2) to give decimal places even if there are none eg. 10.00 instead of 10? not a major thing just trying to neaten up a readout.

We want to do more of those nice string manipulation features as time goes on. there is a hack i have done in the past where i print some 0s @ the location i know they might need to be, then i do some modulus math to figure out where i need to print the value i have. Its dumb :P

I will surely accept a padding PR on github ;)

Edited by erendrake
Link to comment
Share on other sites

@InvertedBlack

Gaiiden

has a rover script here http://forum.kerbalspaceprogram.com/threads/92945-kOS-0-13-1-Script-RCS-Thrust-Controller-%28v1-1%29-automated-maneuver-node-execution.

If you want to just use lat & lon as way points (instead of game objects)i would suggest looking into great circle navigation. Which will give you a variable heading for the shortest path between 2 co-ordinates not essential but it helps when navigating near the poles.

Edit: Here is the equation for heading (tlat &tlon are target latitude and target longitude respectively)

LOCK heading TO ARCTAN2(SIN(tLon-SHIP:LONGITUDE)*COS(tLat),(COS(SHIP:LATITUDE)*SIN(tLat))-(SIN(SHIP:LATITUDE)*COS(tLat)*COS(tLon-SHIP:LONGITUDE))). 

great circle nav can also be used to find surface distance but i don't have the equation for that to hand.

Even the rover script (which uses game objects) is a bit complicated for me to piece through and figure out. I really want to just start from scratch and assemble something homebrew without having to reverse engineer an elaborate example. I found the reference documentation extremely helpful, but the single mention of WheelThrottle and WheelSteering contains no information whatsoever about their proper syntax and usage. I found many of Gaiden's questions about this topic earlier in this thread while they were developing that rover driver but I still for my life can't find a simple snip of code that shows the syntax for both Wheelthrottle and Wheelsteering and am quite bummed at this.

Apparently in Wheelsteering's history it could be locked, then at another time it was by Raw Control.... at various points in the code's life WheelSteering could actually be set to a Bearing, which sounds extremely helpful.

I understand that the documentation contains gaps of information here or there as it can be difficult to find the time to draft a complete set of information but if anyone actually understands the syntax of Wheelsteering and Wheelthrottle and can use each in a sentence, please oh yes please do share.

Thank you for your time and input everyone, I greatly appreciate it. =]

Link to comment
Share on other sites

Wrong script. See my sig for the rover driver code. I got all my info from the docs. There's really not that much difference at all between wheelsteering and steering

Link to comment
Share on other sites

We want to do more of those nice string manipulation features as time goes on. there is a hack i have done in the past where i print some 0s @ the location i know they might need to be, then i do some modulus math to figure out where i need to print the value i have. Its dumb :P

I will surely accept a padding PR on github ;)

Yes. wrappers around the various string manipulators like substring, toupper, and so on would be nice. It might be a good idea to wait until there's such a thing as methods wrapping things in kOS (upcoming future feature) so we can make it work like it should (var.toupper() rather than toupper(var)).

Link to comment
Share on other sites

Wrong script. See my sig for the rover driver code. I got all my info from the docs. There's really not that much difference at all between wheelsteering and steering

Ah, I see. Thank you muchly, Gaiiden. So assuming this, 'LOCK WHEELSTEERING TO HEADING( 180, 0 ).' would turn the wheels in the direction it took to point at heading 180 and 'LOCK WHEELTHROTTLE TO 1.0.' would assign full thrust? That sounds excellent.

I assume if I wanted to attempt Raw Control vs Cooked with these it's not possible, but I love that I can set a heading. :) I'll report back if I incur any further issue, thank you so much for the help everyone!

Link to comment
Share on other sites

I assume if I wanted to attempt Raw Control vs Cooked with these it's not possible, but I love that I can set a heading. :) I'll report back if I incur any further issue, thank you so much for the help everyone!

Beware, the last time I tried using LOCK WHEELSTEERING to a heading, I discovered a bug in the steering code that caused it to drive in circles when you try to drive exactly due north. I don't remember if the fix ever made it into the code or not, because this was way back when the project was being rearranged and moved to a new github location so it might have gotten lost on the way. Give it a try and see if it works.

The problem was, essentially, that it just tried to turn left if the current compass heading was higher than desired, or right if the current compass heading was lower than desired. When you are just a *little* bit to the left of 0 degrees, your heading is not -0.001 degrees. It's +359.999 degrees. The code thought "oh noes, I need to turn 359.999 degrees to the left to correct this. I'm *really* far off."

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...