Force-Vector Design: Roller Coaster Centerline Modelling (Part II)

Intro

In 2016, during my final year of engineering courses for my bachelor’s degree, I felt inspired to write my own script for generating a roller coaster centerline through the methodology of force-vector design (“FVD” for short). Developing the code was a moderate challenge, with some unknown math and computer simulation concepts I had to tackle along the way, but I ultimately managed to figure it out. I originally wrote the code in MATLAB, but I’m confident it could translate into similar languages like Python fairly easily. The end result was a script that produces a centerline path for a roller coaster model through inputs of distance, vertical and horizontal G-force, and banking (or “roll”). My original post for this project can be found on my old online portfolio, at this link. This past year, I decided to revisit the project, polish it up a bit, and share the code with everyone in the chances it could help others interested in the topic. But before I get to the actual code, here is a bit of background on force-vector design.

What is Force-Vector Design?

The foundation for force-vector design is based on the physics of dynamic motion resulting from forces acting upon an object. In this case, the object is a roller coaster car, and the forces acting upon the object are the vertical and lateral g-forces you want the object to experience as a rider of the roller coaster. Additionally, at times there may be roll (banking) of the track, which adds another layer of complexity to the simulation of motion. Taking both the g-forces and roll into account, and assigning them to segments of distance (or segments of time in other applications) along a track, you begin to have a way to define the path (or centerline) of the roller coaster.

Typically, when people think about a roller coaster and the forces they experience on the ride, they think about it in this order: the track curved upwards (like when going through a loop, for example), and this pushed me into my seat and kept me there without feeling like I was going to fall out (feeling the positive vertical g-forces). This is correct intuition, but force-vector design reverses this methodology. Instead, the path of the coaster is defined by the forces you want the rider to experience. Revisiting the previous example, if I have a roller coaster car that is moving along a path that is completely level, and I want the track to curve upwards, I would have to apply positive vertical g-force on the roller coaster car, over a length of track. Thus, when simulating this scenario, the roller coaster car would experience positive vertical g-force pushing down as the track curves upwards.

With the input of initial parameters for position, velocity, roll, pitch, yaw, vertical g-force, and lateral g-force, then followed by defined segments of vertical g-force, lateral g-force, and roll, we are able to design a ride path that looks like the figures below, which are the MATLAB plots of the first and second halves of the coaster developed to test my FVD script:

MATLAB plot of part 1 of the hypercoaster track centerline
MATLAB plot of part 2 of the hypercoaster track centerline

Part 1 of the track begins at the top of the lift hill and continues along until midway through the ride, where part 2 picks up. The track was split into two parts because my code could only accommodate a certain number of length segments, and also the inaccuracies in my estimation of friction, air resistance, etc. gets amplified the longer the track is within each instance of the script. Additionally, you will notice the main drop off of the lift hill was modified from the code when looking at the No Limits model. This was done for aesthetic reasons, to match the Intamin hypercoaster-style ride I ended up basing the trackwork off of. The MATLAB code for Part 1 and Part 2 of the track can be found at end of this article, titled “Track Centerline Code – Section #1” and “Track Centerline Code – Section #2”.

Exporting MATLAB Data into NoLimits 2 Roller Coaster Simulator

Once each section of the track layout was completed within MATLAB, the next step was to export the track path data into a format that could be imported into NoLimits 2. The key to doing that was to recognize that the NoLimits 2 track element file (“.NL2ELEM”) is really a .xlm file containing data that defines the track position at intervals along its path. Below is a screenshot of a .NL2ELEM file opened in Notepad++ in order to show how the file is configured:

A .NL2ELEM file viewed in Notepad++

In order to create a .NL2ELEM file from scratch, I needed to have the x, y, and z positions of each vertex, as well as the components of the forward vector (called the “unit accel vector” in my code) and the components of the side vector perpendicular to the forward vector (called the “unit side vector” in my code) for each vertex. Proper formatting of the text, including the angle brackets (“<” and “>”) and following the indentation scheme of the different groups of information in the files was required as well.

I decided to separate this .NL2ELEM-generating code from the main centerline-developing code in order to isolate any troubleshooting when figuring out how to properly generate the element files. Therefore, I needed to configure my centerline code to export individual .xlm files with the raw numerical data for all the the vertex locations along the path, and their respective forward vector components, and side vector components. The .NL2ELEM-generating code then opened these .xlm files to import the data, and configured it into the proper format for a .NL2ELEM file. This MATLAB code can be found in full at end of this article, titled “.NL2ELEM Generation Code”.

Once the .NL2ELEM file was created, it could be imported into NoLimits 2, and the track simulation could be generated. I took the track design that was developed with the script and designed some simple supports for the track and a landscape/environment for the ride. The sliding image comparison below shows the MATLAB plot versus the NoLimits 2 simulation (from roughly the same angle).

MATLAB plot vs NoLimits 2 Simulation

And lastly, below are some pictures and videos of the coaster in its entirety. Pardon the lack of scenery besides landscaping and sharp transitions between banking and g-force changes. As written, the script only utilizes a linear transition between changing g-forces and banking values, rather than a sinusoidal transition that would allow for a smoother gradient between values. However, the coaster still rides pretty smooth and overall turned out rather nicely for the style I wanted to recreate. Enjoy!

NoLimits 2 POV video of the coaster
NoLimits 2 offride video of the coaster
Index
Track Centerline Code – Section #1


%{
Copyright 2016 by Ian A. Kopack.

>>> SOURCE LICENSE >>>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation (www.fsf.org).

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

A copy of the GNU General Public License is available at
http://www.fsf.org/licensing/licenses

>>> END OF LICENSE >>>
%}

%{
Programmer:     Ian A. Kopack
Date:           April 15th, 2016
Description:    Force-Vector Heartline Design
Matlab ver:     R2015b
%}

set(0,'defaultfigurecolor',[1 1 1])
clc; clear all
refreshdata

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% global parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

U_k = 0.0295;        % [] friction coefficient
g = 9.81;            % [m/s^2] gravitational constant
dist_stp = 0.50;     % [m] distance step (CHECK FOR CONVERGENCE)
ttl_stps = 3000;     % [] total steps for track sim (includes 1st pos at zero)

heartline = 1.1;     % [m] heartline (distance from track)
rail_spacing = 1.5;  % [m] distance between track rails across 

smooth_iterations = 10;    % number of times smoothed

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% inital parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

init_xPos = 0/3.3;    % [m] init x postion
init_yPos = 200/3.3;  % [m] init y postion
init_zPos = 0/3.3;    % [m] init z postion

init_xVel = 8/2.2;  % [m/s] init x velocity
init_yVel = 0.00;   % [m/s] init y velocity
init_zVel = 0.00;   % [m/s] init z velocity

init_roll  = 0.00*pi()/180; % [rad] roll angle
init_pitch = 0.00*pi()/180; % [rad] pitch angle
init_yaw   = 0.00*pi()/180; % [rad] yaw angle

init_vertG  =  1.00; % vertical G-force output
init_latG   =  0.00; % lateral G-force output

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% gForce and banking inputs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%     XXXXX   XXXXX   vertG   distn   latrG   distn   bankg   distn
%     XXXXX   XXXXX    [g]     [m]     [g]     [m]    [deg]    [m]
AA = [00.00   99999   1.000   5.000   0.000   99999   0.000   20.00;
      00.00   00.00   0.000   15.00   0.000   00.00   25.00   30.00;
      00.00   00.00   0.000   20.00   0.000   00.00   25.00   30.00;
      00.00   00.00   3.750   20.00   0.000   000.0   00.00   30.00;
      00.00   00.00   3.750   57.00   0.000   00.00   00.00   100.0;
      00.00   00.00   0.000   20.00   0.000   00.00   35.00   30.00;
      00.00   00.00   0.000   70.00   0.000   00.00   70.00   70.00;
      00.00   00.00   3.500   20.00   0.000   00.00  -40.00   40.00;
      00.00   00.00   3.500   70.00   0.000   00.00  -20.00   40.00;
      00.00   00.00   0.000   20.00   0.000   00.00  -90.00   80.00;
      00.00   00.00   0.000   30.00   0.000   00.00   30.00   40.00;
      00.00   00.00   2.950   40.00   0.000   00.00  -50.00   50.00;
      00.00   00.00   3.000   25.00   0.000   00.00   00.00   47.00;
      00.00   00.00   1.250   30.00   0.000   00.00   00.00   15.00;
      00.00   00.00   0.000   10.00   0.000   00.00  -25.00   20.00;
      00.00   00.00   2.200   40.00   0.000   00.00  -70.00   30.00;
      00.00   00.00   2.000   20.00   0.000   00.00  -35.00   95.00;
      00.00   00.00  -0.500   20.00   0.000   00.00  -55.00   28.00;
      00.00   00.00   3.000   20.00   0.000   00.00   00.00   30.00;
      00.00   00.00   3.000   10.00   0.000   00.00   00.00   900.0;
      00.00   00.00   1.500   20.00   0.000   00.00   00.00   00.00;
      00.00   00.00  -0.250   20.00   0.000   00.00   00.00   00.00;
      00.00   00.00  -0.250   18.00   0.000   00.00   00.00   00.00;
      00.00   00.00   2.900   10.00   0.000   00.00   00.00   00.00;
      00.00   00.00   1.700   50.00   0.000   00.00   00.00   00.00;
      00.00   00.00   1.400   15.00   0.000   00.00   00.00   00.00;
      00.00   00.00   1.900   43.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   25.00   0.000   00.00   00.00   00.00;
      00.00   00.00   3.000   20.00   0.000   00.00   00.00   00.00;
      00.00   00.00   2.800   15.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.400   25.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.400   20.00   0.000   00.00   00.00   00.00;
      00.00   00.00   2.000   20.00   0.000   00.00   00.00   00.00;
      00.00   00.00   1.000   15.00   0.000   00.00   00.00   00.00;
      00.00   00.00   1.000   0.000   0.000   00.00   00.00   00.00;
      00.00   00.00   3.000   0.000   0.000   00.00   00.00   00.00;
      00.00   00.00   3.000   0.000   0.000   00.00   00.00   00.00;
      00.00   00.00   1.000   0.000   0.000   00.00   00.00   00.00;
      00.00   00.00   1.000   0.000   0.000   00.00   00.00   00.00;
      00.00   00.00   1.000   0.000   0.000   00.00   00.00   00.00;
      00.00   00.00   1.000   0.000   0.000   00.00   00.00   00.00;
      00.00   00.00   1.000   0.000   0.000   00.00   00.00   00.00;
      00.00   00.00   1.000   0.000   0.000   00.00   00.00   00.00;
      00.00   00.00   1.000   0.000   0.000   00.00   00.00   00.00];

fvd_time_steps = 44;
  
% Rename AA matrix with "gForce" name and convert banking angles to radians
gForce_and_banking_input(:,1:6) = AA(:,1:6);
gForce_and_banking_input(:,7) = AA(:,7).*(pi()/180);
gForce_and_banking_input(:,8) = AA(:,8);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% gForce transition calculations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

vertG_inputValu = gForce_and_banking_input(:,3);
vertG_inputDist = gForce_and_banking_input(:,4);

latG_inputValu = gForce_and_banking_input(:,5);
latG_inputDist = gForce_and_banking_input(:,6);

bank_inputValu = gForce_and_banking_input(:,7);
bank_inputDist = gForce_and_banking_input(:,8);

vertG_transition = zeros(size(vertG_inputValu));
vertG_transition(1) = (vertG_inputValu(1) - init_vertG)/(vertG_inputDist(1));
for ii = 2:(size(gForce_and_banking_input,1))
    vertG_transition(ii) = (vertG_inputValu(ii) - vertG_inputValu(ii-1))/(vertG_inputDist(ii));
end

latG_transition = zeros(size(latG_inputValu));
latG_transition(1) = (latG_inputValu(1) - init_latG)/(latG_inputDist(1));
for ii = 2:(size(gForce_and_banking_input,1))
    latG_transition(ii) = (latG_inputValu(ii) - latG_inputValu(ii-1))/(latG_inputDist(ii));
end

bank_transition = zeros(size(bank_inputValu));
bank_transition(1) = (bank_inputValu(1) - init_roll)/(bank_inputDist(1));
for ii = 2:(size(gForce_and_banking_input,1))
    bank_transition(ii) = (bank_inputValu(ii) - bank_inputValu(ii-1))/(bank_inputDist(ii));
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% limit calculation of values to only the length of the shortest defined
% force or banking input time
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

plot_total_dist(1,1) = sum(gForce_and_banking_input(:,4));
plot_total_dist(2,1) = sum(gForce_and_banking_input(:,6));
plot_total_dist(3,1) = sum(gForce_and_banking_input(:,8));

min(plot_total_dist);

ic = 1;
while ic < ttl_stps
    if ic*dist_stp <= min(plot_total_dist)
    cutoff_step_value_position = (ic - 1);
    else
    cutoff_step_value_position = (ic - 1);
    ic = ttl_stps;
    end
    ic = ic + 1;
    
end

trckstp = zeros(cutoff_step_value_position,1);

for ib = 1:ttl_stps
    if ib*dist_stp <= min(plot_total_dist)
    trckstp(ib) = ib*dist_stp;
    else
    end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% banking and gForce values calculations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

step_banking_gForce_inputs = trckstp;
step_banking_gForce_inputs(1,2) = init_roll;
step_banking_gForce_inputs(1,4) = init_vertG;
step_banking_gForce_inputs(1,5) = init_latG;

%%%%%%%%%% banking %%%%%%%%%%
for p = 2:numel(trckstp)
    if 0 < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:1))
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(1)*dist_stp;
    elseif sum(bank_inputDist(1:1)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:2));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(2)*dist_stp;
    elseif sum(bank_inputDist(1:2)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:3));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(3)*dist_stp;
    elseif sum(bank_inputDist(1:3)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:4));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(4)*dist_stp;
    elseif sum(bank_inputDist(1:4)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:5));      
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(5)*dist_stp;
    elseif sum(bank_inputDist(1:5)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:6));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(6)*dist_stp;
    elseif sum(bank_inputDist(1:6)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:7));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(7)*dist_stp;
    elseif sum(bank_inputDist(1:7)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:8));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(8)*dist_stp;
    elseif sum(bank_inputDist(1:8)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:9));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(9)*dist_stp;
    elseif sum(bank_inputDist(1:9)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:10));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(10)*dist_stp;
    elseif sum(bank_inputDist(1:10)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:11));       
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(11)*dist_stp;
    elseif sum(bank_inputDist(1:11)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:12));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(12)*dist_stp;
    elseif sum(bank_inputDist(1:12)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:13));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(13)*dist_stp;
    elseif sum(bank_inputDist(1:13)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:14));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(14)*dist_stp;
    elseif sum(bank_inputDist(1:14)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:15));      
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(15)*dist_stp;
    elseif sum(bank_inputDist(1:15)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:16));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(16)*dist_stp;
    elseif sum(bank_inputDist(1:16)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:17));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(17)*dist_stp;
    elseif sum(bank_inputDist(1:17)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:18));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(18)*dist_stp;
    elseif sum(bank_inputDist(1:18)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:19));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(19)*dist_stp;
    elseif sum(bank_inputDist(1:19)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:20));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(20)*dist_stp;
    elseif sum(bank_inputDist(1:20)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:21));       
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(21)*dist_stp;
    elseif sum(bank_inputDist(1:21)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:22));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(22)*dist_stp;
    elseif sum(bank_inputDist(1:22)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:23));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(23)*dist_stp;
    elseif sum(bank_inputDist(1:23)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:24));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(24)*dist_stp;
    elseif sum(bank_inputDist(1:24)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:25));      
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(25)*dist_stp;
    elseif sum(bank_inputDist(1:25)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:26));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(26)*dist_stp;
    elseif sum(bank_inputDist(1:26)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:27));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(27)*dist_stp;
    elseif sum(bank_inputDist(1:27)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:28));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(28)*dist_stp;
    elseif sum(bank_inputDist(1:28)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:29));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(29)*dist_stp;
    elseif sum(bank_inputDist(1:29)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:30));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(30)*dist_stp;        
    elseif sum(bank_inputDist(1:30)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:31));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(31)*dist_stp;   
    elseif sum(bank_inputDist(1:31)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:32));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(32)*dist_stp;    
    elseif sum(bank_inputDist(1:32)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:33));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(33)*dist_stp;
    elseif sum(bank_inputDist(1:33)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:33));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(34)*dist_stp;
    elseif sum(bank_inputDist(1:34)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:34));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(35)*dist_stp;
    elseif sum(bank_inputDist(1:35)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:35));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(36)*dist_stp;   
    elseif sum(bank_inputDist(1:36)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:36));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(37)*dist_stp;     
    elseif sum(bank_inputDist(1:37)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:37));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(38)*dist_stp;    
    elseif sum(bank_inputDist(1:38)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:38));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(39)*dist_stp;     
    elseif sum(bank_inputDist(1:39)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:39));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(40)*dist_stp;   
    elseif sum(bank_inputDist(1:40)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:40));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(41)*dist_stp;   
    elseif sum(bank_inputDist(1:41)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:41));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(42)*dist_stp;   
    elseif sum(bank_inputDist(1:42)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:42));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(43)*dist_stp;    
    elseif sum(bank_inputDist(1:43)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:43));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(44)*dist_stp;     
    end
end

%%%%%%%%%% vert gForce %%%%%%%%%%
for p = 2:numel(trckstp)
    if 0 < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:1))
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(1)*dist_stp;
    elseif sum(vertG_inputDist(1:1)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:2));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(2)*dist_stp;
    elseif sum(vertG_inputDist(1:2)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:3));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(3)*dist_stp;
    elseif sum(vertG_inputDist(1:3)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:4));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(4)*dist_stp;
    elseif sum(vertG_inputDist(1:4)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:5));     
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(5)*dist_stp;
    elseif sum(vertG_inputDist(1:5)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:6));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(6)*dist_stp;
    elseif sum(vertG_inputDist(1:6)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:7));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(7)*dist_stp;
    elseif sum(vertG_inputDist(1:7)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:8));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(8)*dist_stp;
    elseif sum(vertG_inputDist(1:8)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:9));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(9)*dist_stp;
    elseif sum(vertG_inputDist(1:9)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:10));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(10)*dist_stp;
    elseif sum(vertG_inputDist(1:10)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:11));   
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(11)*dist_stp;
    elseif sum(vertG_inputDist(1:11)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:12));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(12)*dist_stp;
    elseif sum(vertG_inputDist(1:12)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:13));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(13)*dist_stp;
    elseif sum(vertG_inputDist(1:13)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:14));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(14)*dist_stp;
    elseif sum(vertG_inputDist(1:14)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:15));    
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(15)*dist_stp;
    elseif sum(vertG_inputDist(1:15)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:16));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(16)*dist_stp;
    elseif sum(vertG_inputDist(1:16)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:17));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(17)*dist_stp;
    elseif sum(vertG_inputDist(1:17)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:18));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(18)*dist_stp;
    elseif sum(vertG_inputDist(1:18)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:19));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(19)*dist_stp;
    elseif sum(vertG_inputDist(1:19)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:20));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(20)*dist_stp;
    elseif sum(vertG_inputDist(1:20)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:21));       
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(21)*dist_stp;
    elseif sum(vertG_inputDist(1:21)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:22));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(22)*dist_stp;
    elseif sum(vertG_inputDist(1:22)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:23));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(23)*dist_stp;
    elseif sum(vertG_inputDist(1:23)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:24));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(24)*dist_stp;
    elseif sum(vertG_inputDist(1:24)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:25));      
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(25)*dist_stp;
    elseif sum(vertG_inputDist(1:25)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:26));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(26)*dist_stp;
    elseif sum(vertG_inputDist(1:26)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:27));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(27)*dist_stp;
    elseif sum(vertG_inputDist(1:27)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:28));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(28)*dist_stp;
    elseif sum(vertG_inputDist(1:28)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:29));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(29)*dist_stp;
    elseif sum(vertG_inputDist(1:29)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:30));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(30)*dist_stp;  
    elseif sum(vertG_inputDist(1:30)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:31));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(31)*dist_stp; 
    elseif sum(vertG_inputDist(1:31)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:32));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(32)*dist_stp; 
    elseif sum(vertG_inputDist(1:32)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:33));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(33)*dist_stp; 
    elseif sum(vertG_inputDist(1:33)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:34));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(34)*dist_stp; 
    elseif sum(vertG_inputDist(1:34)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:34));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(35)*dist_stp;
    elseif sum(vertG_inputDist(1:35)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:35));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(36)*dist_stp;  
    elseif sum(vertG_inputDist(1:36)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:36));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(37)*dist_stp;   
    elseif sum(vertG_inputDist(1:37)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:37));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(38)*dist_stp;  
    elseif sum(vertG_inputDist(1:38)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:38));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(39)*dist_stp;   
    elseif sum(vertG_inputDist(1:39)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:39));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(40)*dist_stp;    
    elseif sum(vertG_inputDist(1:40)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:40));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(41)*dist_stp;    
    elseif sum(vertG_inputDist(1:41)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:41));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(42)*dist_stp;     
    elseif sum(vertG_inputDist(1:42)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:42));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(43)*dist_stp;       
    elseif sum(vertG_inputDist(1:43)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:43));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(44)*dist_stp;       
    end
end
 
%%%%%%%%%% lat gForce %%%%%%%%%%
for p = 2:numel(trckstp)
    if 0 < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:1))
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(1)*dist_stp;
    elseif sum(latG_inputDist(1:1)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:2));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(2)*dist_stp;
    elseif sum(latG_inputDist(1:2)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:3));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(3)*dist_stp;
    elseif sum(latG_inputDist(1:3)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:4));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(4)*dist_stp;
    elseif sum(latG_inputDist(1:4)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:5));        
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(5)*dist_stp;
    elseif sum(latG_inputDist(1:5)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:6));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(6)*dist_stp;
    elseif sum(latG_inputDist(1:6)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:7));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(7)*dist_stp;
    elseif sum(latG_inputDist(1:7)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:8));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(8)*dist_stp;
    elseif sum(latG_inputDist(1:8)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:9));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(9)*dist_stp;
    elseif sum(latG_inputDist(1:9)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:10));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(10)*dist_stp;
    elseif sum(latG_inputDist(1:10)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:11));      
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(11)*dist_stp;
    elseif sum(latG_inputDist(1:11)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:12));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(12)*dist_stp;
    elseif sum(latG_inputDist(1:12)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:13));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(13)*dist_stp;
    elseif sum(latG_inputDist(1:13)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:14));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(14)*dist_stp;
    elseif sum(latG_inputDist(1:14)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:15));       
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(15)*dist_stp;
    elseif sum(latG_inputDist(1:15)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:16));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(16)*dist_stp;
    elseif sum(latG_inputDist(1:16)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:17));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(17)*dist_stp;
    elseif sum(latG_inputDist(1:17)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:18));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(18)*dist_stp;
    elseif sum(latG_inputDist(1:18)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:19));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(19)*dist_stp;
    elseif sum(latG_inputDist(1:19)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:20));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(20)*dist_stp;
    elseif sum(latG_inputDist(1:20)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:21));       
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(21)*dist_stp;
    elseif sum(latG_inputDist(1:21)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:22));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(22)*dist_stp;
    elseif sum(latG_inputDist(1:22)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:23));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(23)*dist_stp;
    elseif sum(latG_inputDist(1:23)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:24));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(24)*dist_stp;
    elseif sum(latG_inputDist(1:24)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:25));      
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(25)*dist_stp;
    elseif sum(latG_inputDist(1:25)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:26));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(26)*dist_stp;
    elseif sum(latG_inputDist(1:26)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:27));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(27)*dist_stp;
    elseif sum(latG_inputDist(1:27)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:28));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(28)*dist_stp;
    elseif sum(latG_inputDist(1:28)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:29));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(29)*dist_stp;
    elseif sum(latG_inputDist(1:29)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:30));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(30)*dist_stp;     
    elseif sum(latG_inputDist(1:30)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:31));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(31)*dist_stp; 
    elseif sum(latG_inputDist(1:31)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:32));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(32)*dist_stp; 
    elseif sum(latG_inputDist(1:32)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:33));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(33)*dist_stp; 
    elseif sum(latG_inputDist(1:33)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:34));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(34)*dist_stp;  
    elseif sum(latG_inputDist(1:34)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:34));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(35)*dist_stp; 
    elseif sum(latG_inputDist(1:35)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:35));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(36)*dist_stp;  
    elseif sum(latG_inputDist(1:36)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:36));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(37)*dist_stp;    
    elseif sum(latG_inputDist(1:37)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:37));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(38)*dist_stp;     
    elseif sum(latG_inputDist(1:38)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:38));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(39)*dist_stp;     
    elseif sum(latG_inputDist(1:39)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:39));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(40)*dist_stp;     
    elseif sum(latG_inputDist(1:40)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:40));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(41)*dist_stp;      
    elseif sum(latG_inputDist(1:41)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:41));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(42)*dist_stp;       
    elseif sum(latG_inputDist(1:42)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:42));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(43)*dist_stp;     
    elseif sum(latG_inputDist(1:43)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:43));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(44)*dist_stp;             
    end
end

step_banking_gForce_inputs(1:fvd_time_steps,:)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Smooth input values transitions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

step_banking_gForce_inputs_midsmoothing = step_banking_gForce_inputs;

% in "step_banking_gForce_inputs," banking is column 2, vert is column 4, lat is column 5

for n = 1:smooth_iterations
	for nn = 2:(numel(trckstp) - 1)
        step_banking_gForce_inputs(nn,2) = ((step_banking_gForce_inputs_midsmoothing((nn-1),2) + step_banking_gForce_inputs_midsmoothing((nn+1),2))/2); 
	
    end
    
    step_banking_gForce_inputs_midsmoothing = step_banking_gForce_inputs;
    
end

step_banking_gForce_inputs(1:fvd_time_steps,:)

disp('MESSAGE: smoothing complete')

step_banking_gForce_inputs;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Linear algebra position vector prediction etc
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

velocity_mag = zeros(size(step_banking_gForce_inputs,1),1); % init 4 speed                                      

velocity_vector(1,:) = [init_xVel init_yVel init_zVel]*[cos(init_pitch) sin(init_pitch) 0;
                                                       -sin(init_pitch) cos(init_pitch) 0;
                                                        0               0               1];

velocity_mag(1) = norm(velocity_vector(1,:));                                                                                        

unit_forward_vector(1,:) = velocity_vector(1,:)/norm(velocity_vector(1,:),2);

            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
           
            % correct location of heartline so init position defines track
            % location starting point rather than heartline starting point
            
            pre_heartline_side_vec(1,:) = cross(unit_forward_vector(1,:),[0 1 0]);
            pre_heartline_unit_side_vec(1,:) = pre_heartline_side_vec(1,:)/norm(pre_heartline_side_vec(1,:),2);
            pre_heartline_top_vec(1,:) = cross(pre_heartline_unit_side_vec(1,:),unit_forward_vector(1,:));
            pre_heartline_unit_top_vec(1,:) = pre_heartline_top_vec(1,:)/norm(pre_heartline_top_vec(1,:),2);   
            centerline_position(1,:) = [init_xPos init_yPos init_zPos] + pre_heartline_unit_top_vec(1,:)*heartline;
            
            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

height(1) = unit_forward_vector(1,2)*dist_stp;

side_vec(1,:) = cross(unit_forward_vector(1,:),[0 1 0]);

pre_unit_side_vec(1,:) = side_vec(1,:)/norm(side_vec(1,:),2);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Quaternion rotation math
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
        epsilon = step_banking_gForce_inputs(:,2);
                
                %    q_c(iii)      q_c = @(x) (cos(epsilon(x)))
                %    q_s(iii)      q_s = @(x) (sin(epsilon(x)))
                %    q_t(iii)      q_t = @(x) (1-cos(epsilon(x)))
                %    q_X(iii-1)    q_X = @(x) (unit_forward_vector(x,1))    % if in loop, needs x-1 !!!
                %    q_Y(iii-1)    q_Y = @(x) (unit_forward_vector(x,2))    % if in loop, needs x-1 !!!
                %    q_Z(iii-1)    q_Z = @(x) (unit_forward_vector(x,3))    % if in loop, needs x-1 !!!        
        
                q_c = @(x) (cos(epsilon(x)));
                q_s = @(x) (sin(epsilon(x)));
                q_t = @(x) (1-cos(epsilon(x)));
                q_X = @(x) (unit_forward_vector(x,1));
                q_Y = @(x) (unit_forward_vector(x,2));
                q_Z = @(x) (unit_forward_vector(x,3));

                quaternion(:,:,1) = [   q_t(1)*q_X(1)*q_X(1)+q_c(1)          q_t(1)*q_X(1)*q_Y(1)+q_s(1)*q_Z(1)   q_t(1)*q_X(1)*q_Z(1)-q_s(1)*q_Y(1)   0;...
                                        q_t(1)*q_X(1)*q_Y(1)-q_s(1)*q_Z(1)   q_t(1)*q_Y(1)*q_Y(1)+q_c(1)          q_t(1)*q_Y(1)*q_Z(1)+q_s(1)*q_X(1)   0;...
                                        q_t(1)*q_X(1)*q_Z(1)+q_s(1)*q_Y(1)   q_t(1)*q_Y(1)*q_Z(1)-q_s(1)*q_X(1)   q_t(1)*q_Z(1)*q_Z(1)+q_c(1)          0;...
                                        0                                    0                                    0                                    1];
                   
                pre_unit_side_vec(:,4) = 0;
                unit_side_vec = pre_unit_side_vec*quaternion(:,:,1);
                unit_side_vec = unit_side_vec(:,1:3);
                unit_side_vec(1,:) = unit_side_vec;
                   
                unit_side_vec_stored_data(1,1:3) = unit_side_vec(1,1:3);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                    

pre_unit_accel_vec(1,:) = cross(unit_side_vec(1,:),unit_forward_vector(1,:));

unit_accel_vector(1,:) = pre_unit_accel_vec(1,:)/norm(pre_unit_accel_vec(1,:),2);

accel_vector(1,:) = unit_accel_vector(1,:).*(step_banking_gForce_inputs(1,4).*g - dot([0 g 0],unit_accel_vector(1,:))) + unit_side_vec(1,:).*(step_banking_gForce_inputs(1,5).*g - dot([0 g 0],unit_side_vec(1,:)));



for iii = 2:(size(step_banking_gForce_inputs,1))
    
    height = unit_forward_vector(iii-1,2)*dist_stp;
     
    velocity_mag(iii) = sqrt(velocity_mag(iii-1)^2 - 2*g*(height + U_k*step_banking_gForce_inputs(iii-1,4)*dist_stp));
    
    side_vec(iii,:) = cross(unit_forward_vector(iii-1,:),[0 1 0]);

    pre_unit_side_vec = (side_vec(iii,:)/norm(side_vec(iii,:),2));
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    % Quaternion rotation math (continued)    
    % need to immediately rotate the unit side vector about the unit forward vector using quaternion rotation

            q_c = @(x) (cos(epsilon(x)));
            q_s = @(x) (sin(epsilon(x)));
            q_t = @(x) (1-cos(epsilon(x)));
            q_X = @(x) (unit_forward_vector(x,1));
            q_Y = @(x) (unit_forward_vector(x,2));
            q_Z = @(x) (unit_forward_vector(x,3));
            
            quaternion(:,:,iii) = [   q_t(iii)*q_X(iii-1)*q_X(iii-1)+q_c(iii)                q_t(iii)*q_X(iii-1)*q_Y(iii-1)+q_s(iii)*q_Z(iii-1)   q_t(iii)*q_X(iii-1)*q_Z(iii-1)-q_s(iii)*q_Y(iii-1)   0;...
                                      q_t(iii)*q_X(iii-1)*q_Y(iii-1)-q_s(iii)*q_Z(iii-1)     q_t(iii)*q_Y(iii-1)*q_Y(iii-1)+q_c(iii)              q_t(iii)*q_Y(iii-1)*q_Z(iii-1)+q_s(iii)*q_X(iii-1)   0;...
                                      q_t(iii)*q_X(iii-1)*q_Z(iii-1)+q_s(iii)*q_Y(iii-1)     q_t(iii)*q_Y(iii-1)*q_Z(iii-1)-q_s(iii)*q_X(iii-1)   q_t(iii)*q_Z(iii-1)*q_Z(iii-1)+q_c(iii)              0;...
                                      0                                                      0                                                    0                                                    1];
    
            pre_unit_side_vec(:,4) = 0;
            unit_side_vec = pre_unit_side_vec*quaternion(:,:,iii);
            unit_side_vec = unit_side_vec(:,1:3);
            unit_side_vec_stored_data(iii,1:3) = unit_side_vec(1,1:3);   % 1 in the row designation because because there is only 1
            unit_side_vec(iii,:) = unit_side_vec;
            
                                                       
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    pre_unit_accel_vec(iii,:) = cross(unit_side_vec(iii,:),unit_forward_vector(iii-1,:));
    unit_accel_vector(iii,:) = pre_unit_accel_vec(iii,:)/norm(pre_unit_accel_vec(iii,:),2);
    accel_vector(iii,:) = unit_accel_vector(iii,:).*(step_banking_gForce_inputs(iii,4).*g - dot([0 g 0],unit_accel_vector(iii,:))) + unit_side_vec(iii,:).*(step_banking_gForce_inputs(iii,5).*g - dot([0 g 0],unit_side_vec(iii,:)));
    velocity_vector(iii,:) = velocity_mag(iii).*unit_forward_vector(iii-1,:) + accel_vector(iii,:).*(dist_stp/velocity_mag(iii));
    unit_forward_vector(iii,:) = velocity_vector(iii,:)/norm(velocity_vector(iii,:),2);
    centerline_position(iii,:) = centerline_position(iii-1,:) + velocity_vector(iii,:).*(dist_stp/velocity_mag(iii)); %+ (1/2).*accel_vector(iii,:).*(dist_stp/velocity_magnitude(iii)).*(dist_stp/velocity_magnitude(iii)); <--- Go over this with Dustin

    % track is designed based on the force input directing the heartline
    
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% track visualization components
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    track_C1_side_vec(1,:) = cross(unit_forward_vector(1,:),unit_accel_vector(1,:));
    track_C1_unit_side_vec(1,:) = track_C1_side_vec(1,:)/norm(track_C1_side_vec(1,:),2);
    track_C1_top_vec(1,:) = cross(track_C1_unit_side_vec(1,:),unit_forward_vector(1,:));
    track_C1_unit_top_vec(1,:) = track_C1_top_vec(1,:)/norm(track_C1_top_vec(1,:),2);
    track_C1_position(1,:) = [init_xPos init_yPos init_zPos] - track_C1_unit_side_vec(1,:)*rail_spacing*0.5;
    
    track_C2_side_vec(1,:) = cross(unit_forward_vector(1,:),unit_accel_vector(1,:));
    track_C2_unit_side_vec(1,:) = track_C2_side_vec(1,:)/norm(track_C2_side_vec(1,:),2);
    track_C2_top_vec(1,:) = cross(track_C2_unit_side_vec(1,:),unit_forward_vector(1,:));
    track_C2_unit_top_vec(1,:) = track_C2_top_vec(1,:)/norm(track_C2_top_vec(1,:),2);
    track_C2_position(1,:) = [init_xPos init_yPos init_zPos] + track_C2_unit_side_vec(1,:)*rail_spacing*0.5;
    
    track_C3_side_vec(1,:) = cross(unit_forward_vector(1,:),unit_accel_vector(1,:));
    track_C3_unit_side_vec(1,:) = track_C3_side_vec(1,:)/norm(track_C3_side_vec(1,:),2);
    track_C3_top_vec(1,:) = cross(track_C3_unit_side_vec(1,:),unit_forward_vector(1,:));
    track_C3_unit_top_vec(1,:) = track_C3_top_vec(1,:)/norm(track_C3_top_vec(1,:),2);
    track_C3_position(1,:) = [init_xPos init_yPos init_zPos] - track_C3_unit_top_vec(1,:)*heartline;
    
    
for ccc = 2:(size(step_banking_gForce_inputs,1))

    track_C1_side_vec(ccc,:) = cross(unit_forward_vector(ccc,:),unit_accel_vector(ccc,:));
    track_C1_unit_side_vec(ccc,:) = track_C1_side_vec(ccc,:)/norm(track_C1_side_vec(ccc,:),2);
    track_C1_top_vec(ccc,:) = cross(track_C1_unit_side_vec(ccc,:),unit_forward_vector(ccc,:));
    track_C1_unit_top_vec(ccc,:) = track_C1_top_vec(ccc,:)/norm(track_C1_top_vec(ccc,:),2);
    track_C1_position(ccc,:) = centerline_position(ccc,:) - track_C1_unit_top_vec(ccc,:)*heartline - track_C1_unit_side_vec(ccc,:)*rail_spacing*0.5;

    track_C2_side_vec(ccc,:) = cross(unit_forward_vector(ccc,:),unit_accel_vector(ccc,:));
    track_C2_unit_side_vec(ccc,:) = track_C2_side_vec(ccc,:)/norm(track_C2_side_vec(ccc,:),2);
    track_C2_top_vec(ccc,:) = cross(track_C2_unit_side_vec(ccc,:),unit_forward_vector(ccc,:));
    track_C2_unit_top_vec(ccc,:) = track_C2_top_vec(ccc,:)/norm(track_C2_top_vec(ccc,:),2);
    track_C2_position(ccc,:) = centerline_position(ccc,:) - track_C2_unit_top_vec(ccc,:)*heartline + track_C2_unit_side_vec(ccc,:)*rail_spacing*0.5;

    track_C3_side_vec(ccc,:) = cross(unit_forward_vector(ccc,:),unit_accel_vector(ccc,:));
    track_C3_unit_side_vec(ccc,:) = track_C3_side_vec(ccc,:)/norm(track_C3_side_vec(ccc,:),2);
    track_C3_top_vec(ccc,:) = cross(track_C3_unit_side_vec(ccc,:),unit_forward_vector(ccc,:));
    track_C3_unit_top_vec(ccc,:) = track_C3_top_vec(ccc,:)/norm(track_C3_top_vec(ccc,:),2);
    track_C3_position(ccc,:) = centerline_position(ccc,:) - track_C3_unit_top_vec(ccc,:)*heartline*2;
    
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Raw data export
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Position data for Solidworks, Autocad, etc
dlmwrite('centerline_position.txt',centerline_position,'precision','    %6.3f','delimiter','');
dlmwrite('track_C1_position.txt',track_C1_position,'precision','    %6.3f','delimiter','');
dlmwrite('track_C2_position.txt',track_C2_position,'precision','    %6.3f','delimiter','');
dlmwrite('track_C3_position.txt',track_C3_position,'precision','    %6.3f','delimiter','');

% Position data for MATLAB xml-to-nl2elem code
dlmwrite('xml_centerline_position_data.txt',centerline_position,'precision','    %6.3f','delimiter','');
dlmwrite('xml_unit_accel_vector_data.txt',unit_accel_vector,'precision','    %6.3f','delimiter','');
dlmwrite('xml_unit_side_vec_stored_data.txt',unit_side_vec_stored_data,'precision','    %6.3f','delimiter','');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Plotting position
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

t = datetime('now');
DateString = datestr(t);

figure(1)
plot3((track_C1_position(:,1).*3.3),(track_C1_position(:,3).*3.3),(track_C1_position(:,2).*3.3),'b',(track_C2_position(:,1).*3.3),(track_C2_position(:,3).*3.3),(track_C2_position(:,2).*3.3),'b',(centerline_position(:,1).*3.3),(centerline_position(:,3).*3.3),(centerline_position(:,2).*3.3),'m',(track_C1_position(:,1).*3.3),(track_C1_position(:,3).*3.3),zeros(length(track_C1_position(:,2)),1),'k',(track_C2_position(:,1).*3.3),(track_C2_position(:,3).*3.3),zeros(length(track_C2_position(:,2)),1),'k')
    xlabel('X position (ft)')
    ylabel('Z position (ft)')
    zlabel('Y position (ft)')
    title(DateString)
    legend('track_r_a_i_l_1','track_r_a_i_l_2','heartline','shadow','location','southeast')
    axis equal
    grid on


Track Centerline Code – Section #2


%{
Copyright 2016 by Ian A. Kopack.

>>> SOURCE LICENSE >>>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation (www.fsf.org).

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

A copy of the GNU General Public License is available at
http://www.fsf.org/licensing/licenses

>>> END OF LICENSE >>>
%}

%{
Programmer:     Ian A. Kopack
Date:           April 15th, 2016
Description:    Force-Vector Heartline Design
Matlab ver:     R2015b
%}

set(0,'defaultfigurecolor',[1 1 1])
clc; clear all
refreshdata

%{
1 m/s = 2.2 mph
1 m = 3.3 ft = 39.6 in
%}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% global parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

U_k = 0.0295;        % [] friction coefficient
g = 9.81;            % [m/s^2] gravitational constant
dist_stp = 1.00;     % [m] distance step (CHECK FOR CONVERGENCE)
ttl_stps = 3000;     % [] total steps for track sim (includes 1st pos at zero) [SWITCH BACK TO 40000]

heartline = 1.1;     % [m] heartline (distance from track)
rail_spacing = 1.5;  % [m] distance between track rails across 

smooth_iterations = 10;    % number of times smoothed

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% inital parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

init_xPos = -59.392;    % [m] init x postion
init_yPos = 3.957;  % [m] init y postion
init_zPos = -339.845;    % [m] init z postion

init_xVel = 23.666;  % [m/s] init x velocity
init_yVel = 0.00;   % [m/s] init y velocity
init_zVel = 0.00;   % [m/s] init z velocity

init_roll  = 0.00*pi()/180; % [rad] roll angle
init_pitch = -0.0160007*pi()/180; % [rad] pitch angle
init_yaw   = 0.00*pi()/180; % [rad] yaw angle

init_vertG  =  1.00; % vertical G-force output
init_latG   =  0.00; % lateral G-force output



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% gForce and banking inputs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%     XXXXX   XXXXX   vertG   distn   latrG   distn   bankg   distn
%     XXXXX   XXXXX    [g]     [m]     [g]     [m]    [deg]    [m]
AA = [00.00   99999   1.000   08.00   0.000   99999   0.000   8.000;
      00.00   00.00   1.300   10.00   0.000   00.00   60.00   20.00;
      00.00   00.00   1.000   00.00   0.000   00.00   60.00   10.00;
      00.00   00.00   1.000   35.00   0.000   00.00   0.000   20.00;
      00.00   00.00   1.000   00.00   0.000   00.00   00.00   10.00;
      00.00   00.00   2.500   15.00   0.000   00.00  -120.00  30.00;
      00.00   00.00   2.500   5.000   0.000   00.00   00.00   30.00;
      00.00   00.00   0.000   10.00   0.000   00.00   00.00   130.0;
      00.00   00.00   0.000   34.00   0.000   00.00   61.00   30.00;
      00.00   00.00   2.500   10.00   0.000   00.00   71.00   30.00;
      00.00   00.00   2.500   21.00   0.000   00.00   00.00   50.00;
      00.00   00.00   0.000   10.00   0.000   00.00   00.00   10.00;
      00.00   00.00   0.000   41.00   0.000   00.00   38.00   19.00;
      00.00   00.00   2.500   10.00   0.000   00.00   38.00   0.000;
      00.00   00.00   2.500   17.00   0.000   00.00   00.00   20.00;
      00.00   00.00   0.000   10.00   0.000   00.00   00.00   50.00;
      00.00   00.00   0.000   32.00   0.000   00.00   00.00   00.00;
      00.00   00.00   2.500   10.00   0.000   00.00   00.00   00.00;
      00.00   00.00   2.500   40.00   0.000   00.00   00.00   00.00;
      00.00   00.00   1.000   20.00   0.000   00.00   00.00   00.00;
      00.00   00.00   1.200   20.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   10.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   12.00   0.000   00.00   00.00   00.00;
      00.00   00.00   2.000   10.00   0.000   00.00   00.00   00.00;
      00.00   00.00   2.000   10.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   10.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   5.000   0.000   00.00   00.00   00.00;
      00.00   00.00   1.000   10.00   0.000   00.00   00.00   00.00;
      00.00   00.00   1.000   2.500   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   0.000   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   00.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   00.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   00.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   00.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   00.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   00.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   00.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   00.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   00.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   00.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   00.00   0.000   00.00   00.00   00.00;
      00.00   00.00   0.000   00.00   0.000   00.00   00.00   00.00];

  
fvd_time_steps = 30;
  
% Rename AA matrix with "gForce" name and convert banking angles to radians
gForce_and_banking_input(:,1:6) = AA(:,1:6);
gForce_and_banking_input(:,7) = AA(:,7).*(pi()/180);
gForce_and_banking_input(:,8) = AA(:,8);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% gForce transition calculations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

vertG_inputValu = gForce_and_banking_input(:,3);
vertG_inputDist = gForce_and_banking_input(:,4);

latG_inputValu = gForce_and_banking_input(:,5);
latG_inputDist = gForce_and_banking_input(:,6);

bank_inputValu = gForce_and_banking_input(:,7);
bank_inputDist = gForce_and_banking_input(:,8);

vertG_transition = zeros(size(vertG_inputValu));
vertG_transition(1) = (vertG_inputValu(1) - init_vertG)/(vertG_inputDist(1));
for ii = 2:(size(gForce_and_banking_input,1))
    vertG_transition(ii) = (vertG_inputValu(ii) - vertG_inputValu(ii-1))/(vertG_inputDist(ii));
end

latG_transition = zeros(size(latG_inputValu));
latG_transition(1) = (latG_inputValu(1) - init_latG)/(latG_inputDist(1));
for ii = 2:(size(gForce_and_banking_input,1))
    latG_transition(ii) = (latG_inputValu(ii) - latG_inputValu(ii-1))/(latG_inputDist(ii));
end

bank_transition = zeros(size(bank_inputValu));
bank_transition(1) = (bank_inputValu(1) - init_roll)/(bank_inputDist(1));
for ii = 2:(size(gForce_and_banking_input,1))
    bank_transition(ii) = (bank_inputValu(ii) - bank_inputValu(ii-1))/(bank_inputDist(ii));
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% limit calculation of values to only the length of the shortest defined
% force or banking input time
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

plot_total_dist(1,1) = sum(gForce_and_banking_input(:,4));
plot_total_dist(2,1) = sum(gForce_and_banking_input(:,6));
plot_total_dist(3,1) = sum(gForce_and_banking_input(:,8));

min(plot_total_dist);

ic = 1;
while ic < ttl_stps
    if ic*dist_stp <= min(plot_total_dist)
    cutoff_step_value_position = (ic - 1);
    else
    cutoff_step_value_position = (ic - 1);
    ic = ttl_stps;
    end
    ic = ic + 1;
    
end

trckstp = zeros(cutoff_step_value_position,1);

for ib = 1:ttl_stps
    if ib*dist_stp <= min(plot_total_dist)
    trckstp(ib) = ib*dist_stp;
    else
    end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% banking and gForce values calculations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

step_banking_gForce_inputs = trckstp;
step_banking_gForce_inputs(1,2) = init_roll;
step_banking_gForce_inputs(1,4) = init_vertG;
step_banking_gForce_inputs(1,5) = init_latG;

%%%%%%%%%% banking %%%%%%%%%%
for p = 2:numel(trckstp)
    if 0 < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:1))
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(1)*dist_stp;
    elseif sum(bank_inputDist(1:1)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:2));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(2)*dist_stp;
    elseif sum(bank_inputDist(1:2)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:3));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(3)*dist_stp;
    elseif sum(bank_inputDist(1:3)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:4));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(4)*dist_stp;
    elseif sum(bank_inputDist(1:4)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:5));      
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(5)*dist_stp;
    elseif sum(bank_inputDist(1:5)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:6));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(6)*dist_stp;
    elseif sum(bank_inputDist(1:6)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:7));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(7)*dist_stp;
    elseif sum(bank_inputDist(1:7)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:8));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(8)*dist_stp;
    elseif sum(bank_inputDist(1:8)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:9));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(9)*dist_stp;
    elseif sum(bank_inputDist(1:9)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:10));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(10)*dist_stp;
    elseif sum(bank_inputDist(1:10)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:11));       
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(11)*dist_stp;
    elseif sum(bank_inputDist(1:11)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:12));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(12)*dist_stp;
    elseif sum(bank_inputDist(1:12)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:13));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(13)*dist_stp;
    elseif sum(bank_inputDist(1:13)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:14));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(14)*dist_stp;
    elseif sum(bank_inputDist(1:14)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:15));      
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(15)*dist_stp;
    elseif sum(bank_inputDist(1:15)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:16));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(16)*dist_stp;
    elseif sum(bank_inputDist(1:16)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:17));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(17)*dist_stp;
    elseif sum(bank_inputDist(1:17)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:18));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(18)*dist_stp;
    elseif sum(bank_inputDist(1:18)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:19));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(19)*dist_stp;
    elseif sum(bank_inputDist(1:19)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:20));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(20)*dist_stp;
    elseif sum(bank_inputDist(1:20)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:21));       
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(21)*dist_stp;
    elseif sum(bank_inputDist(1:21)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:22));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(22)*dist_stp;
    elseif sum(bank_inputDist(1:22)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:23));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(23)*dist_stp;
    elseif sum(bank_inputDist(1:23)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:24));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(24)*dist_stp;
    elseif sum(bank_inputDist(1:24)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:25));      
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(25)*dist_stp;
    elseif sum(bank_inputDist(1:25)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:26));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(26)*dist_stp;
    elseif sum(bank_inputDist(1:26)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:27));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(27)*dist_stp;
    elseif sum(bank_inputDist(1:27)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:28));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(28)*dist_stp;
    elseif sum(bank_inputDist(1:28)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:29));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(29)*dist_stp;
    elseif sum(bank_inputDist(1:29)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:30));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(30)*dist_stp;        
    elseif sum(bank_inputDist(1:30)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:31));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(31)*dist_stp;   
    elseif sum(bank_inputDist(1:31)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:32));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(32)*dist_stp;    
    elseif sum(bank_inputDist(1:32)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:33));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(33)*dist_stp;
    elseif sum(bank_inputDist(1:33)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:33));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(34)*dist_stp;
    elseif sum(bank_inputDist(1:34)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:34));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(35)*dist_stp;
    elseif sum(bank_inputDist(1:35)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:35));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(36)*dist_stp;   
    elseif sum(bank_inputDist(1:36)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:36));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(37)*dist_stp;     
    elseif sum(bank_inputDist(1:37)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:37));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(38)*dist_stp;    
    elseif sum(bank_inputDist(1:38)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:38));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(39)*dist_stp;     
    elseif sum(bank_inputDist(1:39)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:39));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(40)*dist_stp;   
    elseif sum(bank_inputDist(1:40)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:40));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(41)*dist_stp;   
    elseif sum(bank_inputDist(1:41)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:41));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(42)*dist_stp;   
    elseif sum(bank_inputDist(1:42)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:42));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(43)*dist_stp;    
    elseif sum(bank_inputDist(1:43)) < trckstp(p) && trckstp(p) <= sum(bank_inputDist(1:43));
        step_banking_gForce_inputs(p,2) = step_banking_gForce_inputs((p-1),2) + bank_transition(44)*dist_stp;     
    end
end

%%%%%%%%%% vert gForce %%%%%%%%%%
for p = 2:numel(trckstp)
    if 0 < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:1))
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(1)*dist_stp;
    elseif sum(vertG_inputDist(1:1)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:2));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(2)*dist_stp;
    elseif sum(vertG_inputDist(1:2)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:3));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(3)*dist_stp;
    elseif sum(vertG_inputDist(1:3)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:4));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(4)*dist_stp;
    elseif sum(vertG_inputDist(1:4)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:5));     
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(5)*dist_stp;
    elseif sum(vertG_inputDist(1:5)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:6));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(6)*dist_stp;
    elseif sum(vertG_inputDist(1:6)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:7));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(7)*dist_stp;
    elseif sum(vertG_inputDist(1:7)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:8));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(8)*dist_stp;
    elseif sum(vertG_inputDist(1:8)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:9));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(9)*dist_stp;
    elseif sum(vertG_inputDist(1:9)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:10));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(10)*dist_stp;
    elseif sum(vertG_inputDist(1:10)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:11));   
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(11)*dist_stp;
    elseif sum(vertG_inputDist(1:11)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:12));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(12)*dist_stp;
    elseif sum(vertG_inputDist(1:12)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:13));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(13)*dist_stp;
    elseif sum(vertG_inputDist(1:13)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:14));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(14)*dist_stp;
    elseif sum(vertG_inputDist(1:14)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:15));    
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(15)*dist_stp;
    elseif sum(vertG_inputDist(1:15)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:16));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(16)*dist_stp;
    elseif sum(vertG_inputDist(1:16)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:17));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(17)*dist_stp;
    elseif sum(vertG_inputDist(1:17)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:18));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(18)*dist_stp;
    elseif sum(vertG_inputDist(1:18)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:19));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(19)*dist_stp;
    elseif sum(vertG_inputDist(1:19)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:20));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(20)*dist_stp;
    elseif sum(vertG_inputDist(1:20)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:21));       
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(21)*dist_stp;
    elseif sum(vertG_inputDist(1:21)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:22));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(22)*dist_stp;
    elseif sum(vertG_inputDist(1:22)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:23));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(23)*dist_stp;
    elseif sum(vertG_inputDist(1:23)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:24));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(24)*dist_stp;
    elseif sum(vertG_inputDist(1:24)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:25));      
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(25)*dist_stp;
    elseif sum(vertG_inputDist(1:25)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:26));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(26)*dist_stp;
    elseif sum(vertG_inputDist(1:26)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:27));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(27)*dist_stp;
    elseif sum(vertG_inputDist(1:27)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:28));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(28)*dist_stp;
    elseif sum(vertG_inputDist(1:28)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:29));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(29)*dist_stp;
    elseif sum(vertG_inputDist(1:29)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:30));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(30)*dist_stp;  
    elseif sum(vertG_inputDist(1:30)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:31));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(31)*dist_stp; 
    elseif sum(vertG_inputDist(1:31)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:32));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(32)*dist_stp; 
    elseif sum(vertG_inputDist(1:32)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:33));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(33)*dist_stp; 
    elseif sum(vertG_inputDist(1:33)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:34));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(34)*dist_stp; 
    elseif sum(vertG_inputDist(1:34)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:34));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(35)*dist_stp;
    elseif sum(vertG_inputDist(1:35)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:35));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(36)*dist_stp;  
    elseif sum(vertG_inputDist(1:36)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:36));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(37)*dist_stp;   
    elseif sum(vertG_inputDist(1:37)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:37));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(38)*dist_stp;  
    elseif sum(vertG_inputDist(1:38)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:38));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(39)*dist_stp;   
    elseif sum(vertG_inputDist(1:39)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:39));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(40)*dist_stp;    
    elseif sum(vertG_inputDist(1:40)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:40));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(41)*dist_stp;    
    elseif sum(vertG_inputDist(1:41)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:41));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(42)*dist_stp;     
    elseif sum(vertG_inputDist(1:42)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:42));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(43)*dist_stp;       
    elseif sum(vertG_inputDist(1:43)) < trckstp(p) && trckstp(p) <= sum(vertG_inputDist(1:43));
        step_banking_gForce_inputs(p,4) = step_banking_gForce_inputs((p-1),4) + vertG_transition(44)*dist_stp;       
    end
end
 
%%%%%%%%%% lat gForce %%%%%%%%%%
for p = 2:numel(trckstp)
    if 0 < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:1))
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(1)*dist_stp;
    elseif sum(latG_inputDist(1:1)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:2));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(2)*dist_stp;
    elseif sum(latG_inputDist(1:2)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:3));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(3)*dist_stp;
    elseif sum(latG_inputDist(1:3)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:4));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(4)*dist_stp;
    elseif sum(latG_inputDist(1:4)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:5));        
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(5)*dist_stp;
    elseif sum(latG_inputDist(1:5)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:6));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(6)*dist_stp;
    elseif sum(latG_inputDist(1:6)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:7));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(7)*dist_stp;
    elseif sum(latG_inputDist(1:7)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:8));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(8)*dist_stp;
    elseif sum(latG_inputDist(1:8)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:9));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(9)*dist_stp;
    elseif sum(latG_inputDist(1:9)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:10));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(10)*dist_stp;
    elseif sum(latG_inputDist(1:10)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:11));      
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(11)*dist_stp;
    elseif sum(latG_inputDist(1:11)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:12));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(12)*dist_stp;
    elseif sum(latG_inputDist(1:12)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:13));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(13)*dist_stp;
    elseif sum(latG_inputDist(1:13)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:14));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(14)*dist_stp;
    elseif sum(latG_inputDist(1:14)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:15));       
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(15)*dist_stp;
    elseif sum(latG_inputDist(1:15)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:16));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(16)*dist_stp;
    elseif sum(latG_inputDist(1:16)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:17));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(17)*dist_stp;
    elseif sum(latG_inputDist(1:17)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:18));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(18)*dist_stp;
    elseif sum(latG_inputDist(1:18)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:19));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(19)*dist_stp;
    elseif sum(latG_inputDist(1:19)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:20));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(20)*dist_stp;
    elseif sum(latG_inputDist(1:20)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:21));       
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(21)*dist_stp;
    elseif sum(latG_inputDist(1:21)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:22));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(22)*dist_stp;
    elseif sum(latG_inputDist(1:22)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:23));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(23)*dist_stp;
    elseif sum(latG_inputDist(1:23)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:24));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(24)*dist_stp;
    elseif sum(latG_inputDist(1:24)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:25));      
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(25)*dist_stp;
    elseif sum(latG_inputDist(1:25)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:26));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(26)*dist_stp;
    elseif sum(latG_inputDist(1:26)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:27));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(27)*dist_stp;
    elseif sum(latG_inputDist(1:27)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:28));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(28)*dist_stp;
    elseif sum(latG_inputDist(1:28)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:29));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(29)*dist_stp;
    elseif sum(latG_inputDist(1:29)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:30));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(30)*dist_stp;     
    elseif sum(latG_inputDist(1:30)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:31));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(31)*dist_stp; 
    elseif sum(latG_inputDist(1:31)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:32));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(32)*dist_stp; 
    elseif sum(latG_inputDist(1:32)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:33));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(33)*dist_stp; 
    elseif sum(latG_inputDist(1:33)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:34));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(34)*dist_stp;  
    elseif sum(latG_inputDist(1:34)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:34));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(35)*dist_stp; 
    elseif sum(latG_inputDist(1:35)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:35));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(36)*dist_stp;  
    elseif sum(latG_inputDist(1:36)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:36));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(37)*dist_stp;    
    elseif sum(latG_inputDist(1:37)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:37));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(38)*dist_stp;     
    elseif sum(latG_inputDist(1:38)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:38));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(39)*dist_stp;     
    elseif sum(latG_inputDist(1:39)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:39));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(40)*dist_stp;     
    elseif sum(latG_inputDist(1:40)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:40));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(41)*dist_stp;      
    elseif sum(latG_inputDist(1:41)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:41));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(42)*dist_stp;       
    elseif sum(latG_inputDist(1:42)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:42));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(43)*dist_stp;     
    elseif sum(latG_inputDist(1:43)) < trckstp(p) && trckstp(p) <= sum(latG_inputDist(1:43));
        step_banking_gForce_inputs(p,5) = step_banking_gForce_inputs((p-1),5) + latG_transition(44)*dist_stp;             
    end
end

step_banking_gForce_inputs(1:fvd_time_steps,:)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Smooth input values transitions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

step_banking_gForce_inputs_midsmoothing = step_banking_gForce_inputs;

% in "step_banking_gForce_inputs," banking is column 2, vert is column 4, lat is column 5

for n = 1:smooth_iterations
	for nn = 2:(numel(trckstp) - 1)
        step_banking_gForce_inputs(nn,2) = ((step_banking_gForce_inputs_midsmoothing((nn-1),2) + step_banking_gForce_inputs_midsmoothing((nn+1),2))/2); 
	
    end
    
    step_banking_gForce_inputs_midsmoothing = step_banking_gForce_inputs;
    
end

step_banking_gForce_inputs(1:fvd_time_steps,:)

disp('MESSAGE: smoothing complete')

step_banking_gForce_inputs;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Linear algebra position vector prediction etc
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

velocity_mag = zeros(size(step_banking_gForce_inputs,1),1); % init 4 speed                                      

velocity_vector(1,:) = [init_xVel init_yVel init_zVel]*[cos(init_pitch) sin(init_pitch) 0;
                                                       -sin(init_pitch) cos(init_pitch) 0;
                                                        0               0               1];

velocity_mag(1) = norm(velocity_vector(1,:));                                                                                        

unit_forward_vector(1,:) = velocity_vector(1,:)/norm(velocity_vector(1,:),2);

            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
           
            % correct location of heartline so init position defines track
            % location starting point rather than heartline starting point
            
            pre_heartline_side_vec(1,:) = cross(unit_forward_vector(1,:),[0 1 0]);
            pre_heartline_unit_side_vec(1,:) = pre_heartline_side_vec(1,:)/norm(pre_heartline_side_vec(1,:),2);
            pre_heartline_top_vec(1,:) = cross(pre_heartline_unit_side_vec(1,:),unit_forward_vector(1,:));
            pre_heartline_unit_top_vec(1,:) = pre_heartline_top_vec(1,:)/norm(pre_heartline_top_vec(1,:),2);   
            centerline_position(1,:) = [init_xPos init_yPos init_zPos] + pre_heartline_unit_top_vec(1,:)*heartline;
            
            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

height(1) = unit_forward_vector(1,2)*dist_stp;

side_vec(1,:) = cross(unit_forward_vector(1,:),[0 1 0]);

pre_unit_side_vec(1,:) = side_vec(1,:)/norm(side_vec(1,:),2);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Quaternion rotation math
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
        epsilon = step_banking_gForce_inputs(:,2);
                
                %    q_c(iii)      q_c = @(x) (cos(epsilon(x)))
                %    q_s(iii)      q_s = @(x) (sin(epsilon(x)))
                %    q_t(iii)      q_t = @(x) (1-cos(epsilon(x)))
                %    q_X(iii-1)    q_X = @(x) (unit_forward_vector(x,1))    % if in loop, needs x-1 !!!
                %    q_Y(iii-1)    q_Y = @(x) (unit_forward_vector(x,2))    % if in loop, needs x-1 !!!
                %    q_Z(iii-1)    q_Z = @(x) (unit_forward_vector(x,3))    % if in loop, needs x-1 !!!        
        
                q_c = @(x) (cos(epsilon(x)));
                q_s = @(x) (sin(epsilon(x)));
                q_t = @(x) (1-cos(epsilon(x)));
                q_X = @(x) (unit_forward_vector(x,1));
                q_Y = @(x) (unit_forward_vector(x,2));
                q_Z = @(x) (unit_forward_vector(x,3));

                quaternion(:,:,1) = [   q_t(1)*q_X(1)*q_X(1)+q_c(1)          q_t(1)*q_X(1)*q_Y(1)+q_s(1)*q_Z(1)   q_t(1)*q_X(1)*q_Z(1)-q_s(1)*q_Y(1)   0;...
                                        q_t(1)*q_X(1)*q_Y(1)-q_s(1)*q_Z(1)   q_t(1)*q_Y(1)*q_Y(1)+q_c(1)          q_t(1)*q_Y(1)*q_Z(1)+q_s(1)*q_X(1)   0;...
                                        q_t(1)*q_X(1)*q_Z(1)+q_s(1)*q_Y(1)   q_t(1)*q_Y(1)*q_Z(1)-q_s(1)*q_X(1)   q_t(1)*q_Z(1)*q_Z(1)+q_c(1)          0;...
                                        0                                    0                                    0                                    1];
                   
                pre_unit_side_vec(:,4) = 0;
                unit_side_vec = pre_unit_side_vec*quaternion(:,:,1);
                unit_side_vec = unit_side_vec(:,1:3);
                unit_side_vec(1,:) = unit_side_vec;
                   
                unit_side_vec_stored_data(1,1:3) = unit_side_vec(1,1:3);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                    

pre_unit_accel_vec(1,:) = cross(unit_side_vec(1,:),unit_forward_vector(1,:));

unit_accel_vector(1,:) = pre_unit_accel_vec(1,:)/norm(pre_unit_accel_vec(1,:),2);

accel_vector(1,:) = unit_accel_vector(1,:).*(step_banking_gForce_inputs(1,4).*g - dot([0 g 0],unit_accel_vector(1,:))) + unit_side_vec(1,:).*(step_banking_gForce_inputs(1,5).*g - dot([0 g 0],unit_side_vec(1,:)));



for iii = 2:(size(step_banking_gForce_inputs,1))
    
    height = unit_forward_vector(iii-1,2)*dist_stp;
     
    velocity_mag(iii) = sqrt(velocity_mag(iii-1)^2 - 2*g*(height + U_k*step_banking_gForce_inputs(iii-1,4)*dist_stp));
    
    side_vec(iii,:) = cross(unit_forward_vector(iii-1,:),[0 1 0]);

    pre_unit_side_vec = (side_vec(iii,:)/norm(side_vec(iii,:),2));
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    % Quaternion rotation math (continued)    
    % need to immediately rotate the unit side vector about the unit forward vector using quaternion rotation

            q_c = @(x) (cos(epsilon(x)));
            q_s = @(x) (sin(epsilon(x)));
            q_t = @(x) (1-cos(epsilon(x)));
            q_X = @(x) (unit_forward_vector(x,1));
            q_Y = @(x) (unit_forward_vector(x,2));
            q_Z = @(x) (unit_forward_vector(x,3));
            
            quaternion(:,:,iii) = [   q_t(iii)*q_X(iii-1)*q_X(iii-1)+q_c(iii)                q_t(iii)*q_X(iii-1)*q_Y(iii-1)+q_s(iii)*q_Z(iii-1)   q_t(iii)*q_X(iii-1)*q_Z(iii-1)-q_s(iii)*q_Y(iii-1)   0;...
                                      q_t(iii)*q_X(iii-1)*q_Y(iii-1)-q_s(iii)*q_Z(iii-1)     q_t(iii)*q_Y(iii-1)*q_Y(iii-1)+q_c(iii)              q_t(iii)*q_Y(iii-1)*q_Z(iii-1)+q_s(iii)*q_X(iii-1)   0;...
                                      q_t(iii)*q_X(iii-1)*q_Z(iii-1)+q_s(iii)*q_Y(iii-1)     q_t(iii)*q_Y(iii-1)*q_Z(iii-1)-q_s(iii)*q_X(iii-1)   q_t(iii)*q_Z(iii-1)*q_Z(iii-1)+q_c(iii)              0;...
                                      0                                                      0                                                    0                                                    1];
    
            pre_unit_side_vec(:,4) = 0;
            unit_side_vec = pre_unit_side_vec*quaternion(:,:,iii);
            unit_side_vec = unit_side_vec(:,1:3);
            unit_side_vec_stored_data(iii,1:3) = unit_side_vec(1,1:3);   % 1 in the row designation because because there is only 1
            unit_side_vec(iii,:) = unit_side_vec;
            
                                                       
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    pre_unit_accel_vec(iii,:) = cross(unit_side_vec(iii,:),unit_forward_vector(iii-1,:));
    unit_accel_vector(iii,:) = pre_unit_accel_vec(iii,:)/norm(pre_unit_accel_vec(iii,:),2);
    accel_vector(iii,:) = unit_accel_vector(iii,:).*(step_banking_gForce_inputs(iii,4).*g - dot([0 g 0],unit_accel_vector(iii,:))) + unit_side_vec(iii,:).*(step_banking_gForce_inputs(iii,5).*g - dot([0 g 0],unit_side_vec(iii,:)));
    velocity_vector(iii,:) = velocity_mag(iii).*unit_forward_vector(iii-1,:) + accel_vector(iii,:).*(dist_stp/velocity_mag(iii));
    unit_forward_vector(iii,:) = velocity_vector(iii,:)/norm(velocity_vector(iii,:),2);
    centerline_position(iii,:) = centerline_position(iii-1,:) + velocity_vector(iii,:).*(dist_stp/velocity_mag(iii)); %+ (1/2).*accel_vector(iii,:).*(dist_stp/velocity_magnitude(iii)).*(dist_stp/velocity_magnitude(iii)); <--- Go over this with Dustin

    % track is designed based on the force input directing the heartline
    
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% track visualization components
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    track_C1_side_vec(1,:) = cross(unit_forward_vector(1,:),unit_accel_vector(1,:));
    track_C1_unit_side_vec(1,:) = track_C1_side_vec(1,:)/norm(track_C1_side_vec(1,:),2);
    track_C1_top_vec(1,:) = cross(track_C1_unit_side_vec(1,:),unit_forward_vector(1,:));
    track_C1_unit_top_vec(1,:) = track_C1_top_vec(1,:)/norm(track_C1_top_vec(1,:),2);
    track_C1_position(1,:) = [init_xPos init_yPos init_zPos] - track_C1_unit_side_vec(1,:)*rail_spacing*0.5;
    
    track_C2_side_vec(1,:) = cross(unit_forward_vector(1,:),unit_accel_vector(1,:));
    track_C2_unit_side_vec(1,:) = track_C2_side_vec(1,:)/norm(track_C2_side_vec(1,:),2);
    track_C2_top_vec(1,:) = cross(track_C2_unit_side_vec(1,:),unit_forward_vector(1,:));
    track_C2_unit_top_vec(1,:) = track_C2_top_vec(1,:)/norm(track_C2_top_vec(1,:),2);
    track_C2_position(1,:) = [init_xPos init_yPos init_zPos] + track_C2_unit_side_vec(1,:)*rail_spacing*0.5;
    
    track_C3_side_vec(1,:) = cross(unit_forward_vector(1,:),unit_accel_vector(1,:));
    track_C3_unit_side_vec(1,:) = track_C3_side_vec(1,:)/norm(track_C3_side_vec(1,:),2);
    track_C3_top_vec(1,:) = cross(track_C3_unit_side_vec(1,:),unit_forward_vector(1,:));
    track_C3_unit_top_vec(1,:) = track_C3_top_vec(1,:)/norm(track_C3_top_vec(1,:),2);
    track_C3_position(1,:) = [init_xPos init_yPos init_zPos] - track_C3_unit_top_vec(1,:)*heartline;
    
    
for ccc = 2:(size(step_banking_gForce_inputs,1))

    track_C1_side_vec(ccc,:) = cross(unit_forward_vector(ccc,:),unit_accel_vector(ccc,:));
    track_C1_unit_side_vec(ccc,:) = track_C1_side_vec(ccc,:)/norm(track_C1_side_vec(ccc,:),2);
    track_C1_top_vec(ccc,:) = cross(track_C1_unit_side_vec(ccc,:),unit_forward_vector(ccc,:));
    track_C1_unit_top_vec(ccc,:) = track_C1_top_vec(ccc,:)/norm(track_C1_top_vec(ccc,:),2);
    track_C1_position(ccc,:) = centerline_position(ccc,:) - track_C1_unit_top_vec(ccc,:)*heartline - track_C1_unit_side_vec(ccc,:)*rail_spacing*0.5;

    track_C2_side_vec(ccc,:) = cross(unit_forward_vector(ccc,:),unit_accel_vector(ccc,:));
    track_C2_unit_side_vec(ccc,:) = track_C2_side_vec(ccc,:)/norm(track_C2_side_vec(ccc,:),2);
    track_C2_top_vec(ccc,:) = cross(track_C2_unit_side_vec(ccc,:),unit_forward_vector(ccc,:));
    track_C2_unit_top_vec(ccc,:) = track_C2_top_vec(ccc,:)/norm(track_C2_top_vec(ccc,:),2);
    track_C2_position(ccc,:) = centerline_position(ccc,:) - track_C2_unit_top_vec(ccc,:)*heartline + track_C2_unit_side_vec(ccc,:)*rail_spacing*0.5;

    track_C3_side_vec(ccc,:) = cross(unit_forward_vector(ccc,:),unit_accel_vector(ccc,:));
    track_C3_unit_side_vec(ccc,:) = track_C3_side_vec(ccc,:)/norm(track_C3_side_vec(ccc,:),2);
    track_C3_top_vec(ccc,:) = cross(track_C3_unit_side_vec(ccc,:),unit_forward_vector(ccc,:));
    track_C3_unit_top_vec(ccc,:) = track_C3_top_vec(ccc,:)/norm(track_C3_top_vec(ccc,:),2);
    track_C3_position(ccc,:) = centerline_position(ccc,:) - track_C3_unit_top_vec(ccc,:)*heartline*2;
    
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Raw data export
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Position data for Solidworks, Autocad, etc
dlmwrite('centerline_position.txt',centerline_position,'precision','    %6.3f','delimiter','');
dlmwrite('track_C1_position.txt',track_C1_position,'precision','    %6.3f','delimiter','');
dlmwrite('track_C2_position.txt',track_C2_position,'precision','    %6.3f','delimiter','');
dlmwrite('track_C3_position.txt',track_C3_position,'precision','    %6.3f','delimiter','');

% Position data for MATLAB xml-to-nl2elem code
dlmwrite('xml_centerline_position_data.txt',centerline_position,'precision','    %6.3f','delimiter','');
dlmwrite('xml_unit_accel_vector_data.txt',unit_accel_vector,'precision','    %6.3f','delimiter','');
dlmwrite('xml_unit_side_vec_stored_data.txt',unit_side_vec_stored_data,'precision','    %6.3f','delimiter','');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Plotting position
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

t = datetime('now');
DateString = datestr(t);

figure(1)
plot3((track_C1_position(:,1).*3.3),(track_C1_position(:,3).*3.3),(track_C1_position(:,2).*3.3),'b',(track_C2_position(:,1).*3.3),(track_C2_position(:,3).*3.3),(track_C2_position(:,2).*3.3),'b',(centerline_position(:,1).*3.3),(centerline_position(:,3).*3.3),(centerline_position(:,2).*3.3),'m',(track_C1_position(:,1).*3.3),(track_C1_position(:,3).*3.3),zeros(length(track_C1_position(:,2)),1),'k',(track_C2_position(:,1).*3.3),(track_C2_position(:,3).*3.3),zeros(length(track_C2_position(:,2)),1),'k')
    xlabel('X position (ft)')
    ylabel('Z position (ft)')
    zlabel('Y position (ft)')
    title(DateString)
    legend('track_r_a_i_l_1','track_r_a_i_l_2','heartline','shadow','location','southeast')
    axis equal
    grid on


.NL2ELEM Generation Code


%{
Copyright 2016 by Ian A. Kopack.

>>> SOURCE LICENSE >>>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation (www.fsf.org).

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

A copy of the GNU General Public License is available at
http://www.fsf.org/licensing/licenses

>>> END OF LICENSE >>>
%}

%{
Programmer:     Ian A. Kopack
Date:           April 15th, 2016
Description:    .NL2elem File Generation from Force-Vector Heartline Design Script
Matlab ver:     R2015b
%}

clc; clear all
refreshdata

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% load the position, acceleration vector (forward vector), and side vector data

centerline_position_data = importdata('xml_centerline_position_data.txt');  % load centerline data
unit_accel_vector_data = importdata('xml_unit_accel_vector_data.txt');  % load acceleration vector (forward vector) data
unit_side_vec_data = importdata('xml_unit_side_vec_stored_data.txt');  % load side vector data

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% reorient the data so the position data begins at zero

for i = 1:size(centerline_position_data,1)

    position_data_reoriented(i,1) = (centerline_position_data(i,3) - centerline_position_data(1,3)).*(-1);
    position_data_reoriented(i,2) = (centerline_position_data(i,2) - centerline_position_data(1,2));
    position_data_reoriented(i,3) = (centerline_position_data(i,1) - centerline_position_data(1,1)).*(-1);

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% roll values are strangely reversed in NoLimits...?

unit_side_vec_data = unit_side_vec_data.*(-1);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

segments = size(position_data_reoriented,1);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

root_node = com.mathworks.xml.XMLUtils.createDocument('root');

    element_node = root_node.createElement('element');
    root_node.getDocumentElement.appendChild(element_node);

        description_node = root_node.createElement('description');
        description_value = root_node.createTextNode('this is a description');
        description_node.appendChild(description_value);
        element_node.appendChild(description_node);
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% vertex nodes
% first vertex node includes the "strict" node - alternate setup
        
        vertex_node = root_node.createElement('vertex');

            x_node = root_node.createElement('x');
            x_value = root_node.createTextNode(sprintf('%5.5e',position_data_reoriented(1,1)));
            x_node.appendChild(x_value);
            vertex_node.appendChild(x_node);

            y_node = root_node.createElement('y');
            y_value = root_node.createTextNode(sprintf('%5.5e',position_data_reoriented(1,2)));
            y_node.appendChild(y_value);
            vertex_node.appendChild(y_node);

            z_node = root_node.createElement('z');
            z_value = root_node.createTextNode(sprintf('%5.5e',position_data_reoriented(1,3)));
            z_node.appendChild(z_value);
            vertex_node.appendChild(z_node);

            strict_node = root_node.createElement('strict');
            strict_value = root_node.createTextNode('true');
            strict_node.appendChild(strict_value);
            vertex_node.appendChild(strict_node);

        element_node.appendChild(vertex_node);
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    
% middle vertex nodes do not include the "strict" node

for ii = 2:(segments-1)
    
        vertex_node = root_node.createElement('vertex');

            x_node = root_node.createElement('x');
            x_value = root_node.createTextNode(sprintf('%5.5e',position_data_reoriented(ii,1)));
            x_node.appendChild(x_value);
            vertex_node.appendChild(x_node);

            y_node = root_node.createElement('y');
            y_value = root_node.createTextNode(sprintf('%5.5e',position_data_reoriented(ii,2)));
            y_node.appendChild(y_value);
            vertex_node.appendChild(y_node);

            z_node = root_node.createElement('z');
            z_value = root_node.createTextNode(sprintf('%5.5e',position_data_reoriented(ii,3)));
            z_node.appendChild(z_value);
            vertex_node.appendChild(z_node);

        element_node.appendChild(vertex_node);

end      
            
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% final vertex node again includes the "strict" node - alternate setup
        
        vertex_node = root_node.createElement('vertex');

            x_node = root_node.createElement('x');
            x_value = root_node.createTextNode(sprintf('%5.5e',position_data_reoriented(segments,1)));
            x_node.appendChild(x_value);
            vertex_node.appendChild(x_node);

            y_node = root_node.createElement('y');
            y_value = root_node.createTextNode(sprintf('%5.5e',position_data_reoriented(segments,2)));
            y_node.appendChild(y_value);
            vertex_node.appendChild(y_node);

            z_node = root_node.createElement('z');
            z_value = root_node.createTextNode(sprintf('%5.5e',position_data_reoriented(segments,3)));
            z_node.appendChild(z_value);
            vertex_node.appendChild(z_node);

            strict_node = root_node.createElement('strict');
            strict_value = root_node.createTextNode('true');
            strict_node.appendChild(strict_value);
            vertex_node.appendChild(strict_node);

        element_node.appendChild(vertex_node);
  
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% roll nodes
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%u_vector = zeros(size(position_data_reoriented,1),3);
%r_vector = zeros(size(position_data_reoriented,1),3);

u_vector = unit_accel_vector_data;
r_vector = unit_side_vec_data;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

for iii = 1:segments;

        roll_node = root_node.createElement('roll');

            ux_node = root_node.createElement('ux');
            ux_value = root_node.createTextNode(sprintf('%5.5e',u_vector(iii,1)));
            ux_node.appendChild(ux_value);
            roll_node.appendChild(ux_node);

            uy_node = root_node.createElement('uy');
            uy_value = root_node.createTextNode(sprintf('%5.5e',u_vector(iii,2)));
            uy_node.appendChild(uy_value);
            roll_node.appendChild(uy_node);

            uz_node = root_node.createElement('uz');
            uz_value = root_node.createTextNode(sprintf('%5.5e',u_vector(iii,3)));
            uz_node.appendChild(uz_value);
            roll_node.appendChild(uz_node);
            
            rx_node = root_node.createElement('rx');
            rx_value = root_node.createTextNode(sprintf('%5.5e',r_vector(iii,1)));
            rx_node.appendChild(rx_value);
            roll_node.appendChild(rx_node);

            ry_node = root_node.createElement('ry');
            ry_value = root_node.createTextNode(sprintf('%5.5e',r_vector(iii,2)));
            ry_node.appendChild(ry_value);
            roll_node.appendChild(ry_node);

            rz_node = root_node.createElement('rz');
            rz_value = root_node.createTextNode(sprintf('%5.5e',r_vector(iii,3)));
            rz_node.appendChild(rz_value);
            roll_node.appendChild(rz_node);

            coord_node = root_node.createElement('coord');
            coord_position = linspace(0,segments,segments)./segments;
            coord_value = root_node.createTextNode(sprintf('%5.5e',coord_position(iii)));
            coord_node.appendChild(coord_value);
            roll_node.appendChild(coord_node);
            
        element_node.appendChild(roll_node);

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%write the data to a .nl2elem file
%write the data to a .xlm file (FOR TROUBLESHOOTING AND REVIEW) 

xmlwrite('NL2elem_test_2016_09_30.nl2elem',root_node);
xmlwrite('XML_test_2016_09_30.xml',root_node);


Taking the new website for a test drive

Hello! Welcome! Glad you could stop by!

My name is Ian, and I am a roller coaster geek, builder, theme park designer, music producer, and adventurer in search of memorable experiences. I grew up in Pennsylvania and found my way out west to Los Angeles following my career in themed entertainment. I’m currently working as a Technical Director designing rides and experiences for parks, museums, and other entertainment venues all around the world.

Now, although my day-to-day work is centered around designing and producing entertainment experiences, I tend to find myself diving into many other hobbies in my free time as well, and that is the intention of this blog-type format in this section of my website. I want to share the interesting things I’m working on and recap some of the projects I’ve done in the past.

With that said, enjoy exploring this site, and I’m glad to have you here.

-IAK