afranius
Members-
Posts
13 -
Joined
-
Last visited
Content Type
Profiles
Forums
Developer Articles
KSP2 Release Notes
Everything posted by afranius
-
I've been really enjoying the new economy system in 0.24. However, as Squad stated previously, part of the intent for career mode is to serve as a tutorial for new players. This makes it a bit too easy for more experienced players, and I find that I rarely actually have to worry about funding when designing ships, since parts are cheap and funding is plentiful. Could anyone suggest an existing or in-development mod that aims to make the economy harder, perhaps by reducing mission payout, harder missions, or more expensive parts? If one doesn't exist, I might just go in and crank up the cost of all parts by, say, 10x. Also, could anyone suggest a good tech tree mod that makes for a harder progress that you think might work well with the new economy system? I remember there was a tree floating a while back (called traditional tech I think) that made it necessary to start out with planes and rovers before going into space. That might work well with the mission system, since most early missions require testing parts in atmosphere, which could be done with reusable planes to save on cost, while collecting the funds necessary to build an expensive disposable rocket.
-
Could the size of the SOI be affected by the other nearby bodies, which did change? The weird elliptical orbit with the exit node at the apoapsis was pretty strange. It should be easy to replicate by entering an orbit with periapsis at 55 km, and then raising the apoapsis to get an escape -- you should get the escape node before actually reaching escape velocity, and it will be very apparent in map view (the orbit looks a bit like a horseshoe with a small gap at the top). Perhaps spacing the moons out a little bit more would solve this issue. The original Jool system was far too tight anyway, and even the stock game had a number of SOI-related bugs because of it.
-
Something seems pretty screwy with the Laythe SOI, perhaps it's too small? I got into an elliptical orbit at below escape velocity, but still had an SOI exit node at the apoapsis. I also managed to get a Laythe intercept with a "free" orbital injection, which should be impossible unless I somehow manage to enter the SOI at below escape velocity. Otherwise, it looks really interesting!
-
Van Allen Belts and Planetary Magnetospheres
afranius replied to Fractal_UK's topic in KSP1 Mod Development
You might find this paper useful for ideas about magnetic radiation shielding. It's a bit antiquated though, so there may be a more modern treatment: http://www.islandone.org/Settlements/MagShield.html#one On further investigation, this is a summary from a more recent workshop on the subject of shielding. The summary is not very detailed, but some of the citations might be useful: http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20050180620_2005179931.pdf And here is another one, with more technical details: http://www.sciencedirect.com/science/article/pii/S1350448706000928# -
I looked through the bug tracker and couldn't find anything about this -- wondering if anyone else has this problem: I'm trying to connect two vessels on the ground with a winch and a dismountable connector, and while manipulating the winch (often right after docking the winch ship with the ship that has the dismountable connector mounted on it), the screen (except for HUD) turns black, velocity indicator reads "NaN", and the altitude indicator starts to scroll through nonsense numbers like "111111" "222222", etc. If I go back to space center, it's all black until I restart the game. When I load the save, if the vessels are already docked by the winch, first the vessel disappears immediately, and about a second later I get the black screen again. If I saved before I docked them, it's fine, but when I dock them via winch I get black screen again. Any ideas? I'm running a number of other mods, so it may be an interaction with those: DeadlyRentry, Ioncross, B9, WarpPlugin, Firespitter, a few others.
-
[WIP] Newtonian Orbital Mechanics plugin (maybe?)
afranius replied to Mattasmack's topic in KSP1 Mod Development
Why do you want such large time steps? There are only a few dozen gravity-producing bodies, you can probably do RK3 or something with a small step size and still comfortably run in real time. You might also want to read up on symplectic integrators if you want to preserve energy (you probably do). Having lots of ships in orbit might make things a bit more challenging, but probably not exceedingly so. At worst you might have to run the integrator in a parallel thread. -
Modern jets have TWR about 1.0, and engines with about 100 kN of thrust. The KSP engines have 100 kN of thrust (150 for turbojet), so that's pretty close. I guess they are a little bit light, but the way KSP handles jet engines is a little weird anyway, since the "engine" is just the nozzle, and the engine itself seems to just be hidden somewhere... maybe that's why it has such strange TWR?
-
This is bothering me a bit as well. Does anyone have a link to the source code for the patched 0.20.2 version? I wouldn't mind taking a glance at it to see if I could fix the wobbly joints, but I could only find the binaries.
-
I don't usually write my own solvers (I've written PGS for real-time LCPs, but that's about it), but from using external libraries, I generally find that adding more variables to linearly constrained problems tends to be much faster than switching to nonlinear constraints. For the lower spherical bound, since most engines only gimbal a little, you could probably get a pretty good pyramid approximation for the "floor" of the frustrum (so approximate the hemisphere with a pyramid). That way, the solution is exact at zero gimbal and full gimbal (where it will probably end up most of the time anyway), and is still feasible in the middle (just lower thrust). Anyway, just an idea, good luck
-
Just came here from my thread where you linked this, I guess you had the same idea about CP-based balancing Instead of QCQP, why don't you use polygonal cone approximations (instead of a cone, use an n-sided polygonal pyramid basis with non-negative coefficients)? These are very commonly used in simulating frictional contacts, and they usually work well and keep the problem linear. That might make your life easier.
-
You mean thrustTransforms? Hmm... What I did was thrustTransforms.forward and transformed it by the inverse ship transform to place it in ship coordinates (like the rest of the quantities). I gathered from the Unity documentation that thrustTransforms.forward is in world space. It's actually very close to the part transform transform.up, but off by a few degrees, which actually makes a big difference. I wonder if thrust vectoring is part of the issue? I'm guessing thrustTransforms.forward gives the actual (vectored) thrust direction, and balancing the fuel to that has a nasty positive feedback effect -- the engine gimbals to stay balanced, fuel is rebalanced so that is the new set point, drains a little, and the engine has to gimbal even more, so the fuel is rebalanced to be even more uneven. In that case, any thoughts on how to get non-vectored thrust direction? The MoveFuel function simply moves fuel so that the center of mass is aligned with the target position (center of thrust) on a plane defined by a specified normal (thrust direction). If you have a way to compute CoL, you could very easily use the same function. You can also turn off projection, in which case it will ignore the thrust direction and just align CoM and target in 3D. This might be useful if you want to move the CoM to match the initial CoM position for example (if you balanced your aircraft just right in the SPH and want to rebalance in flight to match).
-
I coded up a little script to rebalance fuel tanks so that the center of mass is centered over the center of thrust, which is pretty useful for VTOL planes or asymmetric rockets. I didn't find anything else that has quite this functionality. It's kind of a cute problem, technically its a quadratic program, but I implemented a very simplified variant of projected Gauss Seidel that seems to more or less do the job. I just integrated it into Kerbal Engineering (since I didn't want to add yet another part to all my ships), but I thought I would post the code in case anyone found it useful. It's pretty simple, just a static function that takes a vessel as input. In my implementation, I just hooked it up to a UI button. If anyone wants to take this and integrate it into a proper mod, please be my guest, I'm releasing this as public domain (anyone can do anything they want with it). It might make a nice addition to something like MechJeb or one of those fuel balancing mods. There are a few shortcomings. For example, fuel is transferred instantly, it might be nice to have some delay for the sake of realism. Also, I can't seem to figure out a good way to figure out the direction an engine fires. I use the engine rotation as a proxy, but I don't think this is the best way to do it (it probably won't handle things like the B9 VTOL engines). I tried using thrustTransforms, but I think those are mainly for the VFX, as they are very inaccurate (I get thrust lines that point way off at a diagonal, resulting in very inaccurate balance). Here is a screenshot of me flying some monstrosity with this thing. It doesn't really fly without automatic fuel balancing, for obvious reasons... not that I have any idea why anyone would want something like that to fly: Here is the code: using System; using UnityEngine; namespace Engineer { public class FuelBalancer { // Set this to true to enable debugging printouts. private static bool debugging = false; public static void BalanceFuel(bool value, Vessel vessel) { // Only execute if button is pressed. if (!value) return; // Go through current engines and computer center of thrust. Vector3 thrustCenter = new Vector3(0,0,0); Vector3 thrustVector = new Vector3(0,0,0); bool bEngineFound = false; foreach(Part part in vessel.Parts) { foreach(PartModule module in part.Modules) { if(module is ModuleEngines) { ModuleEngines engine = (ModuleEngines)module; if (engine.EngineIgnited) { // Found at least one engine. bEngineFound = true; // Get thrust position. Vector3 eCenter = vessel.transform.InverseTransformPoint(engine.transform.position); // Figure out the thrust direction... there has got to be a better way to do this. Vector3 eVector = engine.transform.up; // Undo ship rotation and apply maximum thrust. eVector = vessel.transform.InverseTransformDirection(eVector)*engine.maxThrust; // Compute new thrust center. Vector3 numerator = Vector3.Cross(thrustCenter, thrustVector) + Vector3d.Cross(eCenter, eVector) - Vector3.Cross(eCenter, eVector + thrustVector); Vector3 denominator = Vector3.Cross(thrustCenter, thrustVector + eVector) - Vector3.Cross(eCenter, thrustVector + eVector); float u = 0; if (Math.Abs(denominator.x) >= 1e-8) u = numerator.x / denominator.x; else if (Math.Abs(denominator.y) >= 1e-8) u = numerator.y / denominator.y; else if (Math.Abs(denominator.z) >= 1e-8) u = numerator.z / denominator.z; else u = 0.5f; thrustCenter = Vector3.Lerp(eCenter, thrustCenter, u); // Add the values together to get the thrust vector. thrustVector = thrustVector + eVector; } } } } if (bEngineFound) { // Only rebalance if we have at least one active engine. // Get center of mass. Vector3 centerOfMass = vessel.findLocalCenterOfMass(); if (debugging) Debug.Log("Initial center of mass: " + (centerOfMass*100.0f).ToString()); // Move the fuel. centerOfMass = MoveFuel(vessel, centerOfMass, thrustCenter, thrustVector, true); // Debug printout to specify the current center of thrust and thrust vector. if (debugging) Debug.Log("Center of thrust: " + (thrustCenter*100.0f).ToString() + " thrust vector: " + thrustVector.ToString() + " center of mass: " + (centerOfMass * 100.0f).ToString()); } } // Transfer fuel to move the center of mass from current position to target. public static Vector3 MoveFuel(Vessel vessel, Vector3 centerOfMass, Vector3 targetPosition, Vector3 targetNormal, bool bProject) { float mass = vessel.GetTotalMass(); // Get total mass. int ITERATIONS = 2; // Number of PGS iterations. for (int i = 0; i < ITERATIONS; i++) { // Now step over all tanks and see if we need to transfer. foreach (Part part in vessel.parts) { // Step over all resources in this tank. foreach (PartResource resource in part.Resources) { // Only process nonempty tanks. if (resource.info.density > 0) { // Only move resources that have mass (don't move electricity!) // Read position. Vector3 sourceFullPos = vessel.transform.InverseTransformPoint(part.transform.position); Vector3 sourcePos = sourceFullPos; if (bProject) sourcePos = sourcePos - Vector3.Project(sourcePos, targetNormal); // Step through all other parts for this resource. foreach (Part part2 in vessel.parts) { if (part != part2) { foreach (PartResource resource2 in part2.Resources) { if (resource2.resourceName == resource.resourceName) { // Only consider parts with the same type of resource. // Read position. Vector3 destFullPos = vessel.transform.InverseTransformPoint(part2.transform.position); Vector3 destPos = destFullPos; if (bProject) destPos = destPos - Vector3.Project(destPos, targetNormal); Vector3 normalizedDiff = destPos - sourcePos; normalizedDiff = normalizedDiff.normalized; // Formulate equation so that p2*moveAmount - p1*moveAmount + CoMprojection = CoM double p1 = Vector3.Dot(sourcePos, normalizedDiff); double p2 = Vector3.Dot(destPos, normalizedDiff); double CoMprojection = Vector3.Dot(centerOfMass, normalizedDiff); // Solve for c = CoT_projection - CoMprojection double CoTprojection = Vector3.Dot(targetPosition, normalizedDiff); double c = CoTprojection - CoMprojection; // Compute optimal resource quantity. double moveAmount = 0.0; double denominator = p2 - p1; if (denominator != 0) moveAmount = c / denominator; // Modify by resource density. moveAmount = moveAmount * mass / resource.info.density; // Clamp resource quantity by the amount available in the two tanks. moveAmount = Math.Min(moveAmount, resource.amount); moveAmount = Math.Max(moveAmount, -(resource.maxAmount - resource.amount)); moveAmount = Math.Max(moveAmount, -resource2.amount); moveAmount = Math.Min(moveAmount, resource2.maxAmount - resource2.amount); // Move the resource. resource.amount -= moveAmount; resource2.amount += moveAmount; // Modify the center of mass. centerOfMass = (centerOfMass * mass - sourceFullPos * ((float)(moveAmount * resource.info.density)) + destFullPos * ((float)(moveAmount * resource.info.density))) * (1 / mass); // Print result. if (debugging) Debug.Log("Transferred " + moveAmount.ToString() + " units of " + resource.resourceName + " from " + part.ToString() + " to " + part2.ToString()); if (debugging) Debug.Log("New projected error: " + Vector3.Exclude(targetNormal,centerOfMass-targetPosition).magnitude.ToString()); } } } } } } } } // Return the center of mass. return centerOfMass; } } }