common_swift

Members
  • Content count

    4
  • Joined

  • Last visited

Community Reputation

124 Neutral

About common_swift

  • Rank
    Newbie

Personal Information

  • Interests
    |programmer|
  1. AI will lead to the death of capitalism?

    The title should be changed. It's plausible and Al will lead to death of human labor in its current form, AND how we understand it
  2. Working on small flight sim game, need help with equations

    Purely theoretical, what will looks a step-by-step calculation list with all physical quantities required for an accurate flight simulation? For the question lets assume we are starting from finding object's current mass, and we know we are at 100% throttle (always max thrust) ...  ie at step 1 I'm finding current mass, then at step 2 the wing loading/lift force, at step 3 current AoA/roll/yaw/heading/altitude of the plane and angle between origin and destination point, etc ...
  3. Working on small flight sim game, need help with equations

    Whoa, thanks ...    Yeah, you're right about skin drag and form drag + points of pressure but this will be added later (at least hard-coded classic aircraft designs), I just started from somewhere to have some base and improve it over time - still not reached the moment for adding real elevators, ailerons, etc, at first need a properly working simulation
  4. Hi, just registered because have a problem with my hobby flight-sim game project (written in JavaScript). I'm not sure if the equations in update() method are correct or more important - their order (which one should be first, second, etc) and if I messed something in using metric system (unit conversion). My doubts are caused by that the bot is somehow not capable of going through test map's checkpoints, it crashes at second checkpoint (for now I'm drawing in canvas with 512x512 px dimensions)   The initial values of bot's characteristis are: 100 dragpoints, 15000 kgs thrust, 5000kgs mass, 5 meters height, 15 meters wingspan, 70 sq. meters wingarea and 1000 liters of fuel   This is the sim properties and bot's update() method, I'm starting with fuel level check and continue to expand to calculations needed for setting current position and altitude. It is obvious that sim variables are const (not UPPERCASEd for now) --- var PI = 3.141592; var TAU = 2 * PI; var sim = { state: 1, startTime: 0, playedTime: 0, tempPlayedTime: 0, currentTime: 0, lastTime: 0, dTime: 0, timeProduct: 0, updateTime: 0, worldUpdates: 0, distPerFrame: 0, timeScale: 1, /*< 1 speeds up, > 1 slows down the game, must be fixed*/ timeStep: 0.01667, //in s timeDiff: 0, temp: 0, referenceGravity: 9.80665, //reference gravity in m/sq. s at sea level currentGravity: this.referenceGravity, //in m/sq. s earthRadius: 6371000, //in m earthPowRadius: 40589641000000, //in m geopotentialHeight: 0, //in m distance: 0, x: 0, y: 0, racetrackLength: 0, //in m airReferenceTemperature: 15, //reference air temp in Celsius at sea level, or 288.15 K airReferenceViscosity: 0.01827, //0.00001789 reference air viscosity in centipoise at reference temperature in Celsius, or 0.01827 at reference temperature in Rankine airReferencePressure: 101325, //reference air pressure in Pa at sea level and 15'C air temperature airReferenceDensity: 1.225, //reference air density at sea level in kg/cub.m, or 0.0764734 lb/cub. ft RankineRefTemp: 518.76, //reference air temp in Rankine degree == 15'C SutherlandConstant: 120, //for air gasConstant: 8.3144598, //reference gas constant at sea level, in J/mol Kelvin, or 1545.35 ft lb/lbmol Rankine airMolarMass: 0.0289644, // in kg/mol airLapseRate: 0.0065, //0.0098 reference air lapse rate in Celsius per meter altitude, 0.0065 reference air lapse rate in Kelvin per meter, 0.0019812 in Kelvin per foot airViscosity: this.airReferenceViscosity, airPressure: this.airReferencePressure, airDensity: this.airReferenceDensity, kinematicViscosity: 0, ReynoldsNumber: 0, airCurrentTemp: this.airReferenceTemperature, counter: 0, showFPSMem: true, currentFPS: 0, currentMS: 0, currentMem: 0, showTraj: false, showUnitStats: true, botIdCounter: 0, bots: [], runningBots: 0, targetSize: 10 }; var bot = function() { this.position = {x: 0, y: 0, z: 0}; //z is the ALTITUDE!!! this.destination = {x: 0, y: 0, z: 0}; //z is the ALTITUDE!!! this.distance = 0; //in m this.distanceTravelled = 0; //in m this.altitude = this.position.z; //in m this.pitch = 0; //angle of attack ? in degrees? this.roll = 0; //in degrees? this.yaw = 0; //in degrees? this.heading = 0; //in degrees, 0 - East this.dragCoeff = dragpoints * 0.0001; this.thrust = thrust; //in kgf this.fuel = fuel; //in liters this.mass = mass; //in kg this.loadedMass = this.fuel + this.mass; //in kg this.height = height; //in m this.acceleration = this.thrust / this.loadedMass; //acceleration in m/s this.oldAcceleration = 0; this.velocity = {x: 0, y: 0, z: 0}; //maybe needed for proper integration this.speed = 0; //current speed in m/s this.wingSpan = wingspan; //in m this.wingArea = wingarea; //in sq.m this.wingLoading = this.loadedMass / this.wingArea; //in kg/sq.m this.wingType = wingtype; //1 - flat bottom, 2 - semi-symmetric, 3 - symmetric this.frontalArea = this.wingSpan * this.height; //in sq.m this.liftCoeff = 0; this.liftForce = 0; //in kN this.fuelConsumption = (this.thrust / 100) * 0.035; //0.035 litres per second this.trajectoryLine = traj; this.rotationSpeedX = TAU / 100; //100 FPS this.rotationSpeedY = TAU / 100; this.rotationSpeedZ = TAU / 100; this.size = this.wingArea / 10; //size of the bot on the canvas this.id = sim.botIdCounter; this.target = 0; this.hasTarget = false; this.time = 0; this.startTime = 0; this.isTimed = false; this.state = true; this.distanceBeforeFirstTarget = 0; this.isLanding = false; sim.botIdCounter++; sim.runningBots++; this.update = function() { if (this.fuel >= this.fuelConsumption * sim.timeStep) { this.fuel -= this.fuelConsumption * sim.timeStep; this.loadedMass -= this.fuelConsumption * sim.timeStep; this.acceleration = (this.thrust*sim.timeStep) / this.loadedMass; } else { if (this.target <= targetCount) { this.fuel = 0; //directly set fuel to 0 when it is < 0 or has some very low values ~0.050l if (this.acceleration > 0) this.acceleration -= (this.thrust*sim.timeStep) / this.loadedMass; if (this.acceleration < 0) this.acceleration = 0; } else { this.fuel = 0; this.isTimed = false; //stop the stopwatch for our bot this.state = false; //set state of our bot to inactive sim.runningBots--; //remove our bot from the list with active bots return; //maybe it's better to early exit from the function, execution of the conditions below is useless } } //after fuel check we can calculate all characteristics of our bot this.wingLoading = this.loadedMass / this.wingArea; this.liftCoeff = ((this.loadedMass * sim.currentGravity) / ((sim.airDensity / 2) * pow(this.acceleration, 2) * this.wingArea)) * sim.timeStep; this.liftCoeff = isNaN(this.liftCoeff) ? 0 : this.liftCoeff; this.liftForce = (this.liftCoeff * (0.5*(sim.airDensity * pow(this.acceleration, 2))) * this.wingArea) * sim.timeStep; this.liftForce = isNaN(this.liftForce) ? 0 : this.liftForce; //set destination coords for our bot only once for each destination if (this.hasTarget === false && this.state === true) { this.hasTarget = true; this.destination.x = targets[this.target].x; this.destination.y = targets[this.target].y; this.destination.z = targets[this.target].z; } //calculate the difference between current position and destination for each axis if (this.state === true) { var diffX = this.destination.x - this.position.x; var diffY = this.destination.y - this.position.y; var diffZ = this.destination.z - this.position.z; this.distance = hypot(diffX, diffY, diffZ); //this normalizes the vector, so our calculations for direction and speed in Cartesian system are not skewed if (this.distance > 0) { diffX = diffX / this.distance; diffY = diffY / this.distance; diffZ = diffZ / this.distance; } if (this.distance >= this.size) { //finds direction to the target in radians and convert it to degrees, y BEFORE x!!! var targetAngleXY = atan2(diffY, diffX) * (180 / PI); var targetAngleZ = atan(diffX/diffY) * (180 / PI); //controls bot's altitude to be always bigger than its size, this is a crash prevention if (this.altitude <= this.size) { this.pitch += this.rotationSpeedZ + this.size; } //controls direction and turning speed of our bot, turning speed 0.1667 is one minute or 1/60 degree if (this.heading > targetAngleXY) { this.heading -= (this.rotationSpeedX + this.rotationSpeedY) + 1; } else if (this.heading < targetAngleXY) { this.heading += (this.rotationSpeedX + this.rotationSpeedY) + 1; } //this.heading = targetAngleXY; if (this.pitch > targetAngleZ) { this.pitch -= this.rotationSpeedZ + 1; } else if (this.pitch < targetAngleZ) { this.pitch += this.rotationSpeedZ + 1; } //calculate velocities for each axis this.velocity.x += diffX * this.acceleration * sim.timeStep; this.velocity.y += diffY * this.acceleration * sim.timeStep; this.velocity.z += diffZ * this.acceleration * sim.timeStep; //FIRST calculate Geopotential height //this is gravity-adjusted altitude of our bot, using variation of the gravity with latitude and elevation //based on https://en.wikipedia.org/wiki/Barometric_formula#Source_code sim.geopotentialHeight = (sim.earthRadius * this.altitude / (sim.earthRadius + this.altitude)) / 1000; //in kilometers //calculate current air temperature, in Kelvin //based on https://en.wikipedia.org/wiki/Barometric_formula#Source_code if (sim.geopotentialHeight <= 11) { sim.airCurrentTemp = 288.15 - (6.5 * sim.geopotentialHeight); } // Troposphere else if (sim.geopotentialHeight <= 20) { sim.airCurrentTemp = 216.65 - (6.5 * sim.geopotentialHeight); } // Stratosphere starts else if (sim.geopotentialHeight <= 32) { sim.airCurrentTemp = 196.65 + sim.geopotentialHeight; } else if (sim.geopotentialHeight <= 47) { sim.airCurrentTemp = 228.65 + 2.8 * (sim.geopotentialHeight - 32); } else if (sim.geopotentialHeight <= 51) { sim.airCurrentTemp = 270.65 - (6.5 * sim.geopotentialHeight); }// Mesosphere starts else if (sim.geopotentialHeight <= 71) { sim.airCurrentTemp = 270.65 - 2.8 * (sim.geopotentialHeight - 51); } else if (sim.geopotentialHeight <= 84.85) { sim.airCurrentTemp = 214.65 - 2 * (sim.geopotentialHeight - 71); } //geopotHeight must be less than 84.85 km var KelvinToRankine = sim.airCurrentTemp * 1.8; //in Rankine //calculate current air density and pressure //in Pascals //based on https://en.wikipedia.org/wiki/Barometric_formula#Source_code if (sim.geopotentialHeight <= 11) { sim.airPressure = 101325 * pow(288.15 / sim.airCurrentTemp, -5.255877); } else if (sim.geopotentialHeight <= 20) { sim.airPressure = 22632.06 * exp(-0.1577 * (sim.geopotentialHeight - 11)); } else if (sim.geopotentialHeight <= 32) { sim.airPressure = 5474.889 * pow(216.65 / sim.airCurrentTemp, 34.16319); } else if (sim.geopotentialHeight <= 47) { sim.airPressure = 868.0187 * pow(228.65 / sim.airCurrentTemp, 12.2011); } else if (sim.geopotentialHeight <= 51) { sim.airPressure = 110.9063 * exp(-0.1262 * (sim.geopotentialHeight - 47)); } else if (sim.geopotentialHeight <= 71) { sim.airPressure = 66.93887 * pow(270.65 / sim.airCurrentTemp, -12.2011); } else if (sim.geopotentialHeight <= 84.85) { sim.airPressure = 3.956420 * pow(214.65 / sim.airCurrentTemp, -17.0816); } //altitude must be less than 86 km sim.airDensity = (sim.airPressure * sim.airMolarMass) / (sim.gasConstant * sim.airCurrentTemp); //calculate current air pressure at bot's position sim.airPressureX = 0.5 * sim.airDensity * pow(this.velocity.x, 2); sim.airPressureY = 0.5 * sim.airDensity * pow(this.velocity.y, 2); sim.airPressureZ = 0.5 * sim.airDensity * pow(this.velocity.z, 2); //calculate current air viscosity sim.airViscosity = sim.airReferenceViscosity*(((0.555*sim.RankineRefTemp) + sim.SutherlandConstant)/((0.555*KelvinToRankine) + sim.SutherlandConstant))*pow(KelvinToRankine/sim.RankineRefTemp, 3.2); //in centipose //calculate the Reynolds number so to use the correct drag law sim.kinematicViscosity = sim.airViscosity / sim.airDensity; sim.ReynoldsNumber = (this.acceleration * this.size) / sim.kinematicViscosity; //choose which drag law to use if (sim.ReynoldsNumber < 1) { //for low velocity, linear drag or laminar flow var dragX = 6 * PI * sim.airViscosity * this.size * this.velocity.x; var dragY = 6 * PI * sim.airViscosity * this.size * this.velocity.y; var dragZ = 6 * PI * sim.airViscosity * this.size * this.velocity.z; } else { //for high velocity, quadratic drag or turbulent flow var dragX = sim.airPressureX * this.dragCoeff * this.frontalArea; var dragY = sim.airPressureY * this.dragCoeff * this.frontalArea; var dragZ = sim.airPressureZ * this.dragCoeff * this.frontalArea; } dragX = (isNaN(dragX) ? 0 : dragX*sim.timeStep); dragY = (isNaN(dragY) ? 0 : dragY*sim.timeStep); dragZ = (isNaN(dragZ) ? 0 : dragZ*sim.timeStep); //calculate actual Earth's gravity var distanceFromEarthCenter = sim.earthRadius + this.position.z; sim.currentGravity = sim.referenceGravity * (sim.earthPowRadius / pow(distanceFromEarthCenter, 2)); sim.currentGravity = parseFloat(sim.currentGravity).toFixed(6); //move our bot, maybe a Verlet version? this.acceleration *= 0.5*sim.timeStep; sim.currentGravity *= 0.5*sim.timeStep*sim.timeStep; this.velocity.x += diffX * ((this.acceleration - this.oldAcceleration)/2) * sim.timeStep; this.velocity.y += diffY * ((this.acceleration - this.oldAcceleration)/2) * sim.timeStep; this.velocity.z += diffZ * ((this.acceleration - this.oldAcceleration)/2) * sim.timeStep; var stepX = (this.velocity.x - dragX + this.acceleration); var stepY = (this.velocity.y - dragY + this.acceleration); var stepZ = (this.velocity.z - dragZ - sim.currentGravity + this.liftForce);// + this.acceleration); this.position.x += stepX; this.position.y += stepY; this.position.z += stepZ; this.oldAcceleration = this.acceleration; //calculate current speed and travelled distance of our bot var tmp = hypot(stepX, stepY, stepZ); this.distanceTravelled += tmp; this.speed = (tmp / sim.timeStep); //V = S / t, in m/s this.altitude = this.position.z; }; Hope someone will show me where I did it wrong