Hacker News new | past | comments | ask | show | jobs | submit login

https://www.reddit.com/r/spacex/comments/gigmfh/spacex_iss_d... does it in one line but it's kind of cheating.

Definitely cheating, it's not autopilot. It is just updating your co-ordinates every 500ms on a straight line.

I would like to see a real autopilot written in javascript that you can paste into the console.

I wrote an autopilot[0] for the simulator in JS, which sends key events to the game.

[0]: https://gist.github.com/ForestKatsch/01069f29e8316df11774025...

This is awesome! As a recent student of PIDs, it's even better after uncommenting the createPidDisplay statement on line 566 :)

Only feature request is a 'Do a Barrel Roll!' button.

It's cheating but not as much. It's setting the "motion vector" aka setting the speed at current instant. It's just skipping the controls which are normally setting the "motion vector". For the orientation it's totally cheating though using camera.lookat(target).

Anything is a oneliner when you erase all the `\n`s

Python begs to differ

You can add semicolons at the end of python lines to replace \n's when calling from the command line.

  python3 -c "n=1;print(n)"

How does it deal with code blocks normally defined by indentation? (As an aside, indentation being part of syntax is the only thing keeping me disgusted with python - I like the language otherwise.)

it doesn't :) though it works fine if your terminal allows multiline input:

  python -c "
  for x in stuff:
at some point i even wrote a hacky little wrapper that let you use braces and replaced┬╣ them with spaces+newlines, something like this:

  pyc-wrap "for x in stuff { this(x); that(x); }"
i can dig the code up if you need it :)


though after that i sort of went of the deep end adding perl-style "it" ($_) variables for loop variables:

  for stuff { this($); that($);
(yes, closing braces at the end were optional...)

and for the result of the previous line:

  2; $+1; hex($);
  # roughly translates to:
  x = 2; x = x+1; x = hex(x);
surprisingly pleasant to use for shell-like tasks actually!

edit: almost forgot - if during execution you used a name `foo` not found in locals/globals, `foo` was treated as an external command, and resolved to something like

  lambda *args: os.system('foo', *args)
so that you could (sorta) easily call external commands. fun times :)


┬╣ slightly more involved than a dumb code.replace('{', ':\n') because you need to maintain the indent level... but around that level of sophistication

browser console is a pretty under rated feature. I wish it was used more extensively to teach people how to code. so many cool little hacks you can do on public web pages that cement new concepts quickly.

Very simple P-controller based autopilot derived from the one-liner:

  let a = setInterval(() => { 
      // retrieve values from simulation
      let roll = fixedRotationZ;
      let pitch = fixedRotationX;
      let yaw = fixedRotationY;
      let rpy = new THREE.Vector3(roll, pitch, yaw);
      let rollRate = -rateRotationZ/10.0;
      let pitchRate = -rateRotationX/10.0;
      let yawRate = -rateRotationY/10.0;
      let rpyRate = new THREE.Vector3(rollRate, pitchRate, yawRate);
      let pos = camera.position.clone();
      let posRate = motionVector.clone();
      let targetPos = issObject.position.clone();
      let targetRpy = new THREE.Vector3(0,0,0);
      let dRpy = targetRpy.clone().sub(rpy);
      // P-controller controls target roll,pitch,yaw-rate (targetRpyRate) to reach target orientation
      let targetRpyRate = new THREE.Vector3(
      let minRpyRate = new THREE.Vector3(-1.5, -1.5, -1.5);
      let maxRpyRate = new THREE.Vector3(+1.5, +1.5, +1.5);
      targetRpyRate.clamp(minRpyRate, maxRpyRate)
      let dRpyRate = targetRpyRate.clone().sub(rpyRate);
      // don't calculate with displayed x,y,z but the internal coordinates 
      // (z-axis is forward and backward)
      let dPos = targetPos.clone().sub(pos);
      let d = dPos.length();
      // P-controller controls target motion (targetPosRate) to reach target position
      let targetPosRate = new THREE.Vector3(
          dPos.x / 100.0,
          dPos.y / 100.0,
          dPos.z / 100.0
      let minPosRate = new THREE.Vector3(-0.1, -0.1, -0.01);
      let maxPosRate = new THREE.Vector3(+0.1, +0.1, +0.01);
      // thresholds for bang contRol
      let dRpyRateControlThreshold = new THREE.Vector3(0.0, 0.0, 0.0);
      let dPosRateControlThreshold = new THREE.Vector3(0.001, 0.001, 0.001);
      // define some phases where we want to have different movement behaviour
      if (dRpyRate.length() > 0.1)
          // not correctly oriented, stop movement
          targetPosRate.x = 0;
          targetPosRate.y = 0;
          targetPosRate.z = 0;
      else if (Math.abs(dPos.z) < 20)
          // we are very close, slow approach, larger P-control in lateral
          // directions to correct remaining errors
          minPosRate.z = -0.005;
          maxPosRate.z = +0.005;
          dPosRateControlThreshold.x = 0.01;
          dPosRateControlThreshold.y = 0.01;
          targetPosRate.x = dPos.x;
          targetPosRate.y = dPos.y;
      else if (Math.abs(dPos.z) < 50)
          // we are getting, close, slow down
          minPosRate.z = -0.01;
          maxPosRate.z = +0.01;
          minPosRate.x = -0.01;
          minPosRate.y = -0.01;
          maxPosRate.x = +0.01;
          maxPosRate.y = +0.01;
      else if (Math.abs(dPos.z) < 100)
          // slow down
          minPosRate.z = -0.1;
          maxPosRate.z = +0.1;
      else if ((Math.abs(dPos.x) < 0.05) && (Math.abs(dPos.y) < 0.05))
          // lateral position correct, use maximum approaching speed
          minPosRate.z = -0.2;
          maxPosRate.z = +0.2;
      targetPosRate.clamp(minPosRate, maxPosRate);
      let dPosRate = targetPosRate.clone().sub(posRate);
      // bang control to reach target roll pitch and yaw rate
      if (dRpyRate.x < -dRpyRateControlThreshold.x)
      else if (dRpyRate.x > +dRpyRateControlThreshold.x)
      if (dRpyRate.y < -dRpyRateControlThreshold.y)
      else if (dRpyRate.y > +dRpyRateControlThreshold.y)
      if (dRpyRate.z < -dRpyRateControlThreshold.z)
      else if (dRpyRate.z > +dRpyRateControlThreshold.z)
      // bang control to reach target motion
      if (dPosRate.x < -dPosRateControlThreshold.x)
      else if (dPosRate.x > +dPosRateControlThreshold.x)
      if (dPosRate.y < -dPosRateControlThreshold.y)
      else if (dPosRate.y > +dPosRateControlThreshold.y)
      if (dPosRate.z < -dPosRateControlThreshold.z)
      else if (dPosRate.z > +dPosRateControlThreshold.z)

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact