Stephensons valve gear: Bones, IK solvers, etcetera.

Re: Stephensons valve gear: Bones, IK solvers, etcetera.

Postby cjbarnes5294 » Sun May 29, 2016 5:51 pm

Use as many frames as you need. Animating the drive animation with the script is not much more complicated than referencing the drive anim and wheel nodes in the bogie blueprint. The driving bogie blueprint should be left with no node references if the drive is scripted.

Kind regards,
Chris
The Red Queen Hypothesis, applicable to train sim development?

"Here, you see, it takes all of the running you can do, to keep the same place."
cjbarnes5294
Driver
 
Posts: 398
Images: 82
Joined: Mon Mar 31, 2014 12:40 pm
Location: Gloucestershire/North Yorkshire
Has thanked: 551 times
Been thanked: 187 times

Re: Stephensons valve gear: Bones, IK solvers, etcetera.

Postby TrabantDeLuxe » Mon May 30, 2016 2:48 pm

Wandering way of topic and ahead here, but I figure something like this?

Code: Select all
function update(dTime)
   -- Vectors containing current position and previous position
   local pos{}
   local prevpos{}

   -- Obtain current position
   pos{} = Call(GetPosition)
   -- Obviously, this needs to go neatly into a [x,y,z] vector somehow

   -- Find out how much we have moved using Pythagoras
   dpos = 3DPythagoras(pos{}, prevpos{})

   -- Assuming no slippage, we now know how much to move the wheels
   if NoSlip then
      dWheelAnim = dpos/(2*pi*r)
      Call("Wheelanim:AddTime", dWheelAnim * SomeScalingFactor)
   end

   -- Update prevpos{}
   prevpos{} = pos{}
end


But without the horrible syntax. I've been secretly looking at the .lua files of DTG's older offerings to kinda get a feel for it. Doesn't look as impossible as you'd think at first sight.

Edit Came to think of it, we'd also need to figure out the direction the loco is traveling. And instead of using GetPosition we could do this with GetSpeed, if that is a signed quantity... That would probably prevent funnyness on turntables.
TrabantDeLuxe
Passed Fireman
 
Posts: 247
Images: 7
Joined: Mon Mar 21, 2016 10:10 pm
Location: Delft, NL
Has thanked: 176 times
Been thanked: 263 times

Re: Stephensons valve gear: Bones, IK solvers, etcetera.

Postby JamesLit » Mon May 30, 2016 4:30 pm

Just as a minor thing, even on turntables and traversers trains are considered to be moving forwards or backwards - you get a register of speed on the HUD.
The Forge Simulation | Like us on Facebook!
Owner & Director | Content built with care, not compromises.
User avatar
JamesLit
Driver
 
Posts: 370
Images: 26
Joined: Mon Apr 07, 2014 3:26 pm
Location: Kent
Has thanked: 433 times
Been thanked: 141 times

Re: Stephensons valve gear: Bones, IK solvers, etcetera.

Postby cjbarnes5294 » Mon May 30, 2016 8:03 pm

Code: Select all
do
local wheelPos = 0;
local wheelSlipFactor = 0;
local wheelLockup = false;
local function WheelPosition (time)
   local speed = Call("GetSpeed");
   local DRIVE_WHEEL_DIAMETER = 2; --m, change as required
   local WHEEL_CIRCUMFERANCE = DRIVE_WHEEL_DIAMETER*math.pi();
   
   --wheelslip
   local wheelslip = Call("GetControlValue", "Wheelslip", 0); --add a wheelslip control to the engine blueprint, min value to 1 and max value to 2 or 3
   local regulator = Call("GetControlValue", "Regulator", 0);
   local reverser = math.abs(Call("GetControlValue", "Reverser", 0));
   local trainBrake = Call("GetControlValue", "TrainBrakeControl", 0);
   local BRAKE_APPLY_NOTCH = 0.2; --set to whatever the application starting notch is
   
   if wheelslip > 1 and trainBrake < BRAKE_APPLY_NOTCH then
      wheelSlipFactor = wheelSlipFactor + 2*regulator*reverser*time; --increase acceleration with more force ie.regulator*cut-off
      if wheelSlipFactor > 1.5 then
         wheelSlipFactor = 1.5;
      end
      wheelLockup = false;
   elseif wheelslip > 1 and trainBrake >= BRAKE_APPLY_NOTCH then
      wheelSlipFactor = 0;
      wheelLockup = true; --crude form of wheelskid by stopping the animation
   else
      wheelSlipFactor = 0;
      wheelLockup = false;
   end
   
   --wheel positioning
   if math.abs(speed) > 0.01 and not wheelLockup then --TS physics are extremely noisy, so that when something should be moving absolutely still the acceleration rapidly oscillates around 0 m/s^2
      local direction;
      local reverser = Call("GetControlValue", "Reverser", 0);
      if reverser >= 0 then
         direction = 1;
      else
         direction = -1;
      end
      wheelPos = wheelPos + (speed + direction*wheelSlipFactor)*time;
      if wheelPos > WHEEL_CIRCUMFERANCE then
         wheelPos = wheelPos - WHEEL_CIRCUMFERANCE;
      elseif wheelPos < 0 then
         wheelPos = wheelPos + WHEEL_CIRCUMFERANCE;
      end
   end
end

local function WheelAnim ()
   
   local NUM_OF_ANIM_FRAMES = 16; --change as required
   Call("SetTime", <anim_name_in_engine_blueprint>, (wheelPos/WHEEL_CIRCUMFERANCE)*(NUM_OF_ANIM_FRAMES/30)); --assume the game runs all anims at 30fps

end

function AnimateWheels (time)
   WheelPosition(time);
   WheelAnim();
end
end

function Initialise ()

end

function OnControlValueChange ( name, index, value )

end

function Update (time)
   
   AnimateWheels (time); --do for player locos and AI
   
end


That should do the trick. Note that without proper Newtonian force calculations and Coulomb's Law of Friction, and just using the core adhesion simulation, it's much harder to animate wheelslip convincingly, but I've done a basic form of wheelslip and skid animation that can be worked with for now.

Kind regards,
Chris
The Red Queen Hypothesis, applicable to train sim development?

"Here, you see, it takes all of the running you can do, to keep the same place."
cjbarnes5294
Driver
 
Posts: 398
Images: 82
Joined: Mon Mar 31, 2014 12:40 pm
Location: Gloucestershire/North Yorkshire
Has thanked: 551 times
Been thanked: 187 times

Re: Stephensons valve gear: Bones, IK solvers, etcetera.

Postby TrabantDeLuxe » Mon May 30, 2016 8:31 pm

Chris, many thanks for sharing that. I'm sure it will be of help to many. This kind of stuff should be on some sort of wiki.
TrabantDeLuxe
Passed Fireman
 
Posts: 247
Images: 7
Joined: Mon Mar 21, 2016 10:10 pm
Location: Delft, NL
Has thanked: 176 times
Been thanked: 263 times

Re: Stephensons valve gear: Bones, IK solvers, etcetera.

Postby TrabantDeLuxe » Fri Jul 08, 2016 9:18 am

Image

Major thanks goes out to Chris for the code he posted. My version is just that, but simplified - no wheelslip fancyness:

Code: Select all
function Initialise()
   -- Wheel diameter and then circumference
   WHEEL_DIAMETER = 2.15;
   WHEEL_CIRCUMFERENCE = WHEEL_DIAMETER * 3.14159;

   -- WheelAnim properties
   WHEEL_ANIM_LENGTH = 3.333333;                              -- [s]
   WHEEL_ANIM_POSITION = 0;
   WHEEL_ANIM_TIMESCALE = (WHEEL_ANIM_LENGTH/WHEEL_CIRCUMFERENCE);      -- [s/m]

   Call("BeginUpdate");
end

function Update(dTime)
   -- Get Speed
   local speed = Call("GetSpeed")

   -- Animation Position, being the time of animation:
   WHEEL_ANIM_POSITION = WHEEL_ANIM_POSITION + (speed * dTime * WHEEL_ANIM_TIMESCALE);

   if WHEEL_ANIM_POSITION > WHEEL_ANIM_LENGTH then
      WHEEL_ANIM_POSITION = WHEEL_ANIM_POSITION - WHEEL_ANIM_LENGTH;
   elseif WHEEL_ANIM_POSITION < 0 then
      WHEEL_ANIM_POSITION = WHEEL_ANIM_POSITION + WHEEL_ANIM_LENGTH;
   end
   
   -- Animate!
   Call("SetTime", "wheelanim", WHEEL_ANIM_POSITION);
end


And someone forgot the split pins on the connecting rod...

Edit - What does a semicolon do in lua? Coming from matlab it's automatic for me to just add them to surpress output. Any point in continuing the habit?
TrabantDeLuxe
Passed Fireman
 
Posts: 247
Images: 7
Joined: Mon Mar 21, 2016 10:10 pm
Location: Delft, NL
Has thanked: 176 times
Been thanked: 263 times

Previous

Return to 3DS Max

Who is online

Users browsing this forum: No registered users and 1 guest