Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

679 Good

1 Follower

About CombatWombat

  • Rank

Personal Information

  • Role
  • Interests

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. CombatWombat

    Gyro + Accel values into useful values.

    I think you need to break this down a bit before trying to jump into detecting certain motion paths. Use the gyro and accel data together to form a reliable estimator of orientation and orientation rate of change. Unfortunately this is non-trivial, because it involves things like Kalman or complementary filtering to combine the data, so I'd have to second Nagle's suggestion of investigating a ready made solution from the drone community. You might want to look into using an IMU board designed for drones that also give you magnetometer data for 9 DOF. This can make your orientation estimate better. Some of the drone algorithms will likely have position estimation as well, since they typical do things like "return to take-off point" and enforce "no fly zones" (via GPS, though). Possibly you could plot position estimates over time (essentially the "path") and then check if those points are within some geometry to determine if you are doing "the sweep" motion. Maybe keep a rolling log of the last 100 positions (or however many) and compare that path to a known path that represents the sweep you want to trigger on. Sorry if this is kind of "hand wavy" and general.
  2. CombatWombat

    Action points or not?

    FWIW the "two action" system used in the newer X-COM games had some clunky issues relating to skills/perks that would refund actions or grant bonus actions, because not all actions were "equal". IE: "Implacable" which granted a free "move" action after getting a kill. Could you shoot with that action? Use skill "X"? What about when combined with "Run and Gun" which allowed using both turns to move and then still shoot, but implemented by granted a 3rd action? The interaction of these abilities is *really confusing* and causes even players with hundreds/thousands of hours into the game to sometimes second guess how things will actually work. There's also the weird fact that shooting cost 1 action. But only if its your second action. If you don't move, then it cost both. Weird. Summary: The "simpler" 2 action system can be....not. Depending on implementation.
  3. CombatWombat

    Customizable front page?

    I don't like the left bar. Also get off my lawn. Now excuse me I have to go yell at some clouds.
  4. The radius of you turn will be velocity/turn-rate (for constant velocity and turn rate). Watch your unit conversions. For your example, at maximum 15m/s and 45 deg/s turn rate, you can turn with a radius "R" of 19.09m. Consider this crazy picture. With "R" solved, you can check your target point. Project a distance "R" normal to your velocity vector. From this center point, if your target destination "A" is inside a circle of radius "R", then you cannot reach the target point without slowing down. You will need a circle for "left" and "right" directions obviously, so you can project both normals for this.
  5. CombatWombat

    Limited-Slip Differential and friends

    So like.... https://en.wikipedia.org/wiki/Six-wheel_drive ? I'm now picturing armored personnel carriers racing around Monaco. That's a game I would play. Yes, but again the effects are pretty small except in very specific circumstances (one wheel on low grip surface for example). I'm not saying don't tinker with fancier setups, but it's good to make something simple that works well first and then build on that. This is a big area depending on how deep you want to go. There are commercial software packages out there that simulate engine parameters for purposes of designing real engines such as Dynomation, Pipemax, and many others. There was an old game, Burnout Drag Racing that had a pretty detailed engine simulation built into the game! The short answer to this direct question is "sort of". An engine will make X power at atmospheric pressure (1bar). If you add another 1bar of boost and were somehow able to hold every other variable constant, it would make close to 2X power. If I get some time this evening I will try to write you up something more in depth.
  6. CombatWombat

    Limited-Slip Differential and friends

    Maybe. It's a matter of semantics and will change your other scaling values but shouldn't change how things fundamentally work. In reality it needs some resistance working against the input torque to generate the locking forces. That resistance will be a combination of inertia of the wheels/axles and grip generated by the tire. So, for all intents you can just look at the input torque and trust in the 3rd law that there will be a reaction. For the most part, diff effects will be very subtle. Even if commercial racing games it can be tough to tell the difference between locked and open. Unless you're doing some kind of off-road rock climbing racer. Then it matters. So for AWD, a simple viscous type (tries to equalize speeds with a linear torque based on speed delta) is probably Good Enough™.
  7. CombatWombat

    Limited-Slip Differential and friends

    Hello Vu, Would be nice if someone else would happen a long and try to help, but this place seems quieter than it used to be. I have not tried to do a differential model, but I will try to offer what advice I can... For starters the wiki page on limited slip diffs is actually pretty good, start there if you have not. As a very general overview, I would say there are two types that you may want to model: 1) Torque sensitive types, which encompasses ramp loaded, clutch type, and probably Torsens. The most "general" is the ramp type, since it is very tune-able. 2) Speed sensitive types, which is pretty just much viscous types. So the differential has no idea what the throttle is doing. Most of them use the loads transmitted by the spider gears in various ways to engage the clutches, so they are sensitive to the torque coming in at their input. So you can use your torque after it is multiplied by the transmission gear in your function instead of throttle. I would suggest forgoing geared type LSDs at this moment. They are kind of an oddball in the automotive world (other than Audis?). They are torque sensitive, yes. I don't know in terms of "bias ratio". What happens is the torque causes some leverage on the clutch plates which push them together making the two axles want to turn the same speed. Some very rough psuedo-code. You have to experiment with the values to make sense! driveTorque = getDriveTorqueFromTransmissionOutputShaft(); LSDClutch.friction = 0.5f; LSDClutch.preload = 100.0f; LSDClutch.accelRamp = 1.0f; LSDClutch.decelRamp = 0.5f; if(driveTorque > 0.0f) LSDClutchTorque = preload*friction + accelRamp*driveTorque*friction; else LSDClutchTorque = perload*friction + decelRamp*-driveTorque*friction; speedDelta = axleL.speed - axleR.speed; if(speedDelta > 0) // left axle is faster axleL.torque = 0.5f*driveTorque - LSDClutchTorque; axleR.torque = 0.5f*driveTorque + LSDClutchTorque; else axleL.torque = 0.5f*driveTorque + LSDClutchTorque; axleR.torque = 0.5f*driveTorque - LSDClutchTorque; Yes. As long as the spiders have the same number of teeth. (This will be the case for all automotive differentials).
  8. CombatWombat

    Clutch Modelling Help

    Yes pretty much. Maybe. It's also highly effected by the masses/inertia, tire "stiffness", etc. Yes, but only for one frame. The next frame it might be -500. It might do +500, +500, -500, as it oscillates around the target set point. It should average out very close to 400Nm over enough frames. The linear model I sent in the xls definitely averages out where the transmitted torque is nearly equal to the engine's torque produced (it will not be exact as some of the torque is required to accelerate the engine's own inertia.) It should work similar with the more "digital" model, but you'd need to experiment. Does your model now work properly, but exhibit some other strange quirks? Or does it still completely run-away? So, this is a bit above my pay grade, but in general I'd say this problem could be described as trying to solve a 1D velocity constraint. So I'd wonder if some of the techniques used in collision response (sequential impulse, etc) might be applicable here. Anyone?
  9. CombatWombat

    Clutch Modelling Help

    It does not. Look again at the implementation. Integral is integral of a PID controller. Essentially proportional gets you close, and then integral compensates for the long term error. Real clutch only applies that 500Nm (or whatever) until the nanosecond it's speed has equalized. In discrete time you are stuck applying it for the full 10 ms. This makes it jittery. The proportional model is smoother in this respect. As bmarci said in a previous post, and good plan is to lockup when the sign changes (zero crossing). lastSpeedError = speedError; speedError = engineSpeed - drivelineSpeed; if(sign(lastSpeedError) != sign(speedError)) // Zero crossing, lockup. Used the constant type, but with a lockup method that summed the inertia of the entire driveline and treated it as one part, so the jitteryness wasn't apparent. C++. Engine wasn't mine, but was rolled from scratch for the game.
  10. CombatWombat

    Clutch Modelling Help

    I put something together that may help. Hope .xls can be attached here. If not PM and I will email it. Looking at the chart: First ~50ms or so, clutch is disengaged. You see engine accelerates freely, and gearbox coasts. When clutch engages, engine speed dives down, and gearbox speed increases until they match. In this, I used the linear/proportional model: clutchTorque = SomeConstant*(EngineSpeed-DrivelineSpeed) This works, but there is significant slippage as drivelineSpeed constantly lags behind engineSpeed. So I added an integral term. So the above becomes something like: speedError = EngineSpeed-drivelineSpeed; integralError += speedError; // Make sure not to add to integralError when the clutch is disengaged! clutchTorque = proportionalConstant*speedError + integralConstant*integralError; There is a somewhat narrow range of values for proportionalConstant and integralConstant where this works and is stable. Mostly because I'm using simple Euler integration here at only 100hz. You can experiment with adding derivative term, using better integrators, or upping the refresh rate to get better stability. Or switch to a locked model once the speeds get close. ClutchModel.xls
  11. CombatWombat

    Clutch Modelling Help

    Using that linear model you are simulating something closer to a torque converter (fluid coupling used in automatic transmissions) rather than a clutch. So that's why there's lots of slipping. This can be ok, maybe you just need "stiffer" constants: clutchTorque = 50.0f * (engineRPM - drivelineRPM)... //or clutchTorque = (engineRPM - drivelineRPM)^2 ... //etc Or if you just do: if(engineSpeed > drivelineSpeed) clutchTorque = blah; else clutchTorque = -blah; Then you will have lots of torque as soon as you have 0.00001 slip. You might need a combination of the two to get enough clutch "grab" but not have an unstable simulation. which is a very small amount of torque. Why is it a small amount? You get to choose the frictionConstant to be whatever you desire. Maybe I confused you with using frictionConstant as the name. I did not mean to suggest using something like 0.5 mu friction coefficient. A real clutch has friction coefficient (0.5ish), heavy springs (~5000N+ normal force), and a mean radius (~0.125m) = ~312Nm. Using something like 500-1000 for frictionConstant is not unreasonable. engineNetTorque drives the whole engine blob of mass. Full stop. Period. Do not confuse yourself with fractions of anything. SideB of the clutch doesn't know what engine is doing. It has no idea if there is an engine there at all. Maybe its a hamster in a wheel. Doesn't matter. SideB only knows that SideA is rubbing against it with some normal force and coefficient of friction. You don't have to. You have some torque acting on SideB of the clutch (again, because SideA is rubbing against it, nothing to do with engine). That gets multiplied by the gearbox. You give this to your UnityWheelThing, it performs integration and has a new speed. Next frame, you read that speed, multiply it by gearbox ratio, and that becomes the new speed for clutch-side-B.
  12. CombatWombat

    Clutch Modelling Help

    Your implementation looks close, but let's put some numbers and see where it's going awry. // Let's pick some reasonable starting conditions for trying to accelerate. // EngineRPM: 1000 [104.72 rad/s] // DrivelineRPM: 0 [0 rad/s] // EngineTorque(1000) = 400 Nm // 1st Gear Ratio: 3.00 // Final Drive Ratio: 3.73 float clutchTorque = (engineSpeed - driveTrainSpeed) * (1.0f - clutchInput) * clutchStrength * gearClutch; // (104.72 - 0) * (1.0f - 0.0f) * 10.0f * 1.0f = 1047.2 Nm // This is a lot of torque and should definitely accelerate something! // I would lean towards calling this "clutchReactionTorque" or something similar. // It is the torque acting between the two discs. float engineOutputTorque = currentTotalEngineTorque - clutchTorque; // We're saying engine is making 400Nm, so 400Nm - 1047.2Nm = -647.2Nm. // I would call it "engineNetTorque". We're not actually "outputting" it anywhere. float clutchOutputTorque = (engineOutputTorque + clutchTorque) * (1.0f - clutchInput); // I don't understand this, really. I think it might be where the problem is, but let's try anyways... // (400Nm + 1047.2Nm) * (1.0f - 0.0f) = 1447.2 Nm. // I think correct line would be clutchOutputTorque = clutchTorque; // This is because if you draw FBD of the clutch output plate, it only // knows about clutch input plate and gearbox. It has no idea what engine is actually doing. // It only knows that clutch input plate is rubbing against it with some friction force. float outputTorque = clutchOutputTorque * currentGearRatio * finalDriveRear; // 1447.2Nm * 3.0 * 3.73 = 16194.17 Nm. This is a big number of torques. So something should drive somewhere. currentEngineRPM += radsToRPM((engineOutputTorque * Time.fixedDeltaTime) / engineInertia); // so, we saw that engineOutputTorque is actually -647.2Nm, so the engine should slow down. //finally drives the wheels RR.motorTorque = outputTorque / 2.0f; RL.motorTorque = outputTorque / 2.0f; // Each wheel receives 8097.09 Nm. So assuming the sign is correct (positive number rotates so the car goes forward), // then wheel speed should increase. Drivelinespeed should increase. Enginespeed will decrease as we saw above. // This brings clutch plate speeds closer together. So things appear to be close to working. // Try outputting debug numbers and see if things are behaving as above. What was said above about switching to a "locked clutch" model when speeds equalize is a good idea, but it shouldnt be necessary to get things driving presuming your integrator is stable enough that things don't completely explode. Edit: I would like to clarify that for the model as shown, the clutch and gearbox are both kinda of "virtual". We have not assigned mass or inertia to them. In a way they are just typedefs or "specially named attachment points" of the engine and wheel, since those are the only things with mass in the system. Specifically, the "A" side of the clutch will always have the same speed as the engine. It is effectively part of the engine, but we give it a special name for convenience. Same with the "B" side of the clutch, the gearbox, and the wheels being one "unit". See the following, because MSPaint is THE tool of the future: FreeBodyDiagram
  13. CombatWombat

    Clutch Modelling Help

    Well. It's been a while since I've done this stuff, but let me see if I can help. Let us refer to this diagram. Engine will look like: torqueProduced = throttle * torqueLookup(RPM); // throttle 0.0f - 1.0f frictionTorque = frictionTorqueLookup(RPM); // could be a constant value or linear to RPM. You need to experiment engineNetTorque = torqueProduced + clutchReactionTorque - frictionTorque; engineAngularAcceleration = engineNetTorque/engineInerta; Gearbox will look something like: outputShaftSpeed = drivenWheelRPM; // Let's ignore the differential gearratio and bake it into the gearbox overall ratio. inputShaftSpeed = outputShaftSpeed * currentGearRatio; // Lookup based on current gear selection. outputTorque = clutchReactionTorque * currentGearRatio; Driven wheels: netTorque = reactionTorqueFromGround + (gearboxOutputTorque / numDriveWheels); angularAcceleration = netTorque/wheelInertia; Now the bit to put it all together... The clutch. clutchASpeed = engineRPM; clutchBSpeed = gearboxInputShaftSpeed; // Now, when the clutch is engaged, it wants its two speeds to be equal. // So it should apply reaction torques to try to achieve this. // A naive approach might look something like: clutchTorque = frictionConstant * clutchFactor; // clutchFactor = 0.0f -> 1.0f if(clutchASpeed > clutchBSpeed) reactionTorqueA = -clutchTorque; reactionTorqueB = clutchTorque; else reactionTorqueA = clutchTorque; reactionTorqueB = -clutchTorque; // This may have problems where is oscillates around equal speeds. // Depends on your integrator timestep, masses, etc. // You could experiment with making the reaction torque linear to slip speed, // putting limits as the speeds get close to equal, etc. So, what should happen, is when the engine is faster than the input shaft of the gearbox, the clutch generates a torque that tries to slow the engine and tries to speed up the gearbox. Vice-versa when the engine is slower than the gearbox input. The gearbox multiplies this torque and sends it to the wheels. (Divide it up by the number of drive wheels). As I said, it's been a long time since I've done this. So I could have missed something somewhere, but a similar approach has worked for me in the past.
  14. I don't know if you're still having problems, but what you are describing sounds like a Trapezoidal Motion Profile. Maybe that search term will help you.    
  15. CombatWombat

    Discombobulated input callbacks

    I don't know.  What happens when the camera dies?  How does the dispatcher know to unregister that dangly pointer?  Seems like this just moves that responsibility to the camera object, which then needs to be reimplemented for every game object that registers functions to the dispatcher.  Unless I am misunderstanding.     How do you handle storing the objects (like the camera) in a container (std::vector or similar).  Doesn't that require a copy?   What is the alternative?  Are you saying that the entire Input->MapToActionsWithAContext->ActOnThoseActions model doesn't work well? Or are you saying that the final step of resolving the action via callback does not work well? How else does the game object act upon the action event?   Thanks to both of you.    
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!