pomax / are-we-flying Goto Github PK
View Code? Open in Web Editor NEWWriting auto-pilots in JavaScript for MSFS
Writing auto-pilots in JavaScript for MSFS
Excluding "point and fly" (e.g. jet fighters) and jet liners. The former because even if takeoff works, the AP won't, and the latter because turning off their inbuilt AP is a job in and of itself. There's also a few planes that just refuse to throttle (see #14) so those obviously won't work.
Playing a recording back at 4x or higher shows that we're basically overtrimming at cruise speed, oscillating more than we need to.
Figure out what's keeping the citation/747-8/etc's throttle from moving, even with AP and AT turned off.
Maybe borrow the graphics library from @pomax/bezierinfo-2
elevator-based "trim" can't autoland as well (or at all) as real trim, suggesting we can probably refine the numbers to get it to perform at least better than it does now.
We can't just use the same waypoint transitioning for regular flight path flying: by the time we get to the start we HAVE to be straight on the runway.
add a speed input for ATT so we can set a specific speed we want to maintain
Hi. I have problem running the code. Below is the API server log when i run it while MSFS is up:
No ALOS data folder specified, elevation service will not be available.
Server listening on http://localhost:8080
Connected to MSFS
Registering API server to PAUSE, UNPAUSED, CRASH, and SIM events.
new flight started, resetting autopilot
Server to server socket established
sending MSFS event
sending MSFS event
adding event listener for SIM
registering event listener with the simconnect wrapper
adding event listener for PAUSED
registering event listener with the simconnect wrapper
adding event listener for UNPAUSED
registering event listener with the simconnect wrapper
adding event listener for VIEW
registering event listener with the simconnect wrapper
RecvException { exception: 7, sendId: 21, index: 2 }
RecvException { exception: 7, sendId: 22, index: 2 }
RecvException { exception: 7, sendId: 26, index: 2 }
D:\Programming\Javascript\are-we-flying\node_modules\bytebuffer\dist\bytebuffer-node.js:1403
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.length);
^
RangeError: Illegal offset: 0 <= 616 (+8) <= 620
at module.exports.ByteBufferPrototype.readFloat64 (D:\Programming\Javascript\are-we-flying\node_modules\bytebuffer\dist\bytebuffer-node.js:1403:23)
at RawBuffer.readFloat64 (D:\Programming\Javascript\are-we-flying\node_modules\node-simconnect\dist\RawBuffer.js:75:28)
at Object.read (file:///D:/Programming/Javascript/are-we-flying/node_modules/msfs-simconnect-api-wrapper/simvars/simvar-utils.js:8:44)
at file:///D:/Programming/Javascript/are-we-flying/node_modules/msfs-simconnect-api-wrapper/msfs-api.js:257:52
at Array.forEach (<anonymous>)
at SimConnectConnection.handleDataRequest (file:///D:/Programming/Javascript/are-we-flying/node_modules/msfs-simconnect-api-wrapper/msfs-api.js:256:21)
at SimConnectConnection.emit (node:events:524:35)
at SimConnectConnection.emit (D:\Programming\Javascript\are-we-flying\node_modules\node-simconnect\dist\SimConnectConnection.js:89:22)
at SimConnectConnection._handleMessage (D:\Programming\Javascript\are-we-flying\node_modules\node-simconnect\dist\SimConnectConnection.js:1042:22)
at SimConnectSocket.emit (node:events:512:28)
Node.js v19.5.0
And the web server log:
Server listening on http://localhost:3000
no API server (yet), retrying in 5 seconds
Client socket established.
API Server socket established
going back into wait mode
no API server (yet), retrying in 5 seconds
I don't get this error when I run API server before MSFS. But in that case nothing works. (when i click on take-off nothing happens and I can't put waypoints on map).
Node version: 19.5.0
.env file:
export DATA_FOLDER=
export ALOS_PORT=9000
export WEB_PORT=3000
export API_PORT=8080
export FLIGHT_OWNER_KEY=FOK-12345
Is there anything that I'm missing?
// quarter turn
double Q4 = PI/2;
// some random airport orientation
double randomAngle = random(0, TAU);
// distance from approach point to offset point
double R = 50;
// distance from offset point to secondary offset
// (to force the plane to fly towards the offset)
double R2 = R + 10;
Point end, start, M = new Point(0,0), anchor, o1, o2;
void determineCriticalPoints(int x, int y) {
Point cursor = new Point(x, y);
double ca = cos(randomAngle);
double sa = sin(randomAngle);
// even though M is (0,0), it won't be in the game.
double mx = M.x;
double my = M.y;
start = new Point(mx - 150 * ca, my - 150 * sa);
end = new Point(mx - 200 * ca, my - 200 * sa);
anchor = new Point(mx + 150 * ca, my + 150 * sa);
o1 = null;
o2 = null;
double ax = anchor.x;
double ay = anchor.y;
double v1 = M.x - ax;
double v2 = M.y - ay;
double w1 = cursor.x - ax;
double w2 = cursor.y - ay;
double r = randomAngle;
double a = atan2(w2*v1 - w1*v2, w1*v1 + w2*v2);
Point p = cursor.project(M, anchor);
double d = dist(p, cursor);
if (a > Q4 || a < -Q4) {
o1 = new Point(ax + R * cos(r), ay + R * sin(r));
} else {
if (a > 0) {
r -= Q4;
double cr = cos(r);
double sr = sin(r);
o1 = new Point(ax + R * cr, ay + R * sr);
if (d < 50) o2 = new Point(ax + R2 * cr, ay + R2 * sr);
} else {
r += Q4;
double cr = cos(r);
double sr = sin(r);
o1 = new Point(ax + R * cr, ay + R * sr);
if (d < 50) o2 = new Point(ax + R2 * cr, ay + R2 * sr);
}
}
}
You might like to fly these planes, but the computer sure as hell doesn't.
Just in case you're not using the autopilot but you just want to know what heading to fly without guessing.
The rewrite turned a bunch of captioned figures into plain images, it'd be a good idea to turn those back into captioned figures.
Also, the height map for https://pomax.github.io/are-we-flying/#terrain-follow-mode kind of comes out of left field.
robot of death
The server's running a 5 second poll, but really this should be a signal from MSFS that we can tap in to.
using AILERON_POSITION
and ELEVATOR_POSITION
.
Elevator as horizontal side slides, aileron as vertical top/bottom slides?
If we can run a PID controller in a worker thread, we might be able to run at "Every frame" by getting simconnect to notify us every SIMCONNECT_PERIOD_SIM_FRAME for a small set of values.
This needs benchmarking.
somewhere on the webpage, and in the server code, we should have a timer running that tells us how long we've been flying, as well as how long each leg took (and how long we therefore expect the rest of the flight to still take)
Just to make it more obvious, the landing waypoints, and ideally the landing path, should be a different colour.
So we can plan a flight including autoland before we even take off.
Terrain follow does not appear to work at Anchorage, even though ALOS has tiles for that latitude
because it's just plain weird how shit it autopilots.
It has all the elevation information already anyway, should be able to make this an XYZ tile source for Leaflet to tap into.
Optimizations:
auto-takeoff, waypoint flight, and autolanding can all control and override the altitude, throttle, and heading, and it would be nice to show that to the user by coloring the number inputs somehow.
specifically, plot ground altitude to its own graph, as well as being a dual input for the plane altitude graph, where the plane's plot is green, and the ground (unfilled) plot is the same color as plot limits.
The client should not need to create its own copy of a FlightInformation object by querying the API through the serer, it should be able to just ask the server for its flight information.
It has all kinds of problems. It would be nice to figure out generic solutions for dealing with its nonsense.
we need some kind of "whip" detection
We know our speed, we should be able to work out ETA for unflown waypoints and show that (so you can go make a coffee and maybe mow the lawn while your plane flies on its own for a few hours)
Switch to using https://www.npmjs.com/package/socketless
Dev branch: https://github.com/Pomax/are-we-flying/tree/socketless
We're currently performing an elevator takeoff, but we could also just use the elevator trim instead, using a small positive VS target, so that we wouldn't need to progressive ease back on the elevator and then guess a magic trim value at the time of AP handoff.
This would probably both simplify the code and smooth out the takeoff/AP transition.
All information we need is already in flightInformation
, we should need to make exactly zero API calls during regular operation.
But then also record "which plane" that was for, because a landing that works for a Beaver won't work for a DC-3, for instance?
Maybe only save which airport the landing was for, so that the code can recalculate an approach.
hover mouse, highlight data vertical, update "current value" label with that vertical's value instead.
There has to be a trigger for landing lights, so let's turn them off once we're on our way, and turn them on once we start our glide.
We "bounce" way too much, so we may need some kind of PID controller anyway.
While it makes sense that they're used by the autopilot, it doesn't make the most sense that they're wrapped by the autopilot.
When clicking a waypoint, you should be able to edit:
TER
is onI thought I fixed this, but the API server crashes on unknown vars, which it should never do.
It should be taking "is our drifting across the runway increasing, despite active rudder? If so, increase drift correction" into account.
Some planes refuse to aileron-trim. It might be nice to have code in place that detects "this is doing nothing" and switches to using the stick/yoke instead.
Stagger points along the flight path, past a transition, and (lerp-)target those (moving to next point(s) as we pass them), so that we get (back) on the flight path earlier.
Tuning PID is a full time job, but what if we use a self-tuning PID that survives hot reloads? Eh? Ehhhh?
Simple circle with runway lines
if already scheduled to land somewhere else, remove old landing points first.
it's currently based on distance-to-plane, which only the first waypoint should do (until passed). The rest should set their NM value based on "distance from previous waypoint" so that we know how long each leg is.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.