Skip to content

Commit

Permalink
Merge pull request #26 from ParadigmHyperloop/frontend
Browse files Browse the repository at this point in the history
Refactored the time calculation
  • Loading branch information
walkeri authored Jul 24, 2018
2 parents 1c94763 + ae4b7d8 commit c620b94
Show file tree
Hide file tree
Showing 2 changed files with 200 additions and 101 deletions.
107 changes: 68 additions & 39 deletions src/routes-lib/pod/pod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,44 @@ std::vector<float> Pod::getVelocities(const std::vector<glm::vec3>& points) {
* and end of the route.
*/

std::vector<float> accels;

std::vector<float> vels(calcInitVelocities(lengthMap, points));

//convert the indices for winding up and ramping down to a point in meters on the curve
float begin_accel_distance = lengthMap[_count1];
float end_accel_distance = lengthMap[_count2];

std::vector<float> accels(calcInitAccels(lengthMap, points, begin_accel_distance, end_accel_distance));

// This is a vector of the indices in the points and accels array where the acceleration is larger than g.
std::vector<int> accels_too_high(calcAccelsTooHigh(points));

std::vector<float> finalVels(fixVelocities(vels, lengthMap, accels_too_high, points));

return finalVels;
}

//TODO: Account for going vertical movement
float Pod::timeForCurve(const std::vector<glm::vec3>& points) {

std::vector<float> vels = getVelocities(points);
std::unordered_map<int, float> lengthMap = Bezier::bezierLengthMap(points);

//We now calculate the time for the pod to traverse the route
float time = 0.0;
float dist = 0.0;

//Calculate times.
for (int i = 1; i < vels.size() - 1 ; i++) {
dist = lengthMap[i+1] - lengthMap[i];
time += (dist / vels[i]);
}

return time;

}

std::vector<float> Pod::calcInitVelocities(std::unordered_map<int, float>& lengthMap, const std::vector<glm::vec3>& points) {

//initialize velocity vector, the first value should be 0
std::vector<float> vels;
Expand All @@ -54,16 +91,16 @@ std::vector<float> Pod::getVelocities(const std::vector<glm::vec3>& points) {
}

//Get the index where you stop ramping up
int count = 0;
int count1 = 0;
for (int i = 0; i < points.size(); i++) {
if (vels[i] < DEFAULT_POD_MAX_SPEED) {
count += 1;
count1 += 1;
} else {
count += 0;
count1 += 0;
}
}

int accel_upto_index = count - 1;
int accel_upto_index = count1 - 1;

//used for getting the first index that the pod is winding down at
float newVel2 = 0.0;
Expand All @@ -73,8 +110,8 @@ std::vector<float> Pod::getVelocities(const std::vector<glm::vec3>& points) {
vels[i] = 0.0;
}

//calculate where to start de-accelerating by working from the end of the route. Set all values in between
// to max accel
//calculate velocities during the winding down phase. Set all values in between
//to max vel
for (int i = points.size() - 2; i > accel_upto_index; i--) {
if (vels[i + 1] < DEFAULT_POD_MAX_SPEED) {
newVel2 = glm::sqrt(glm::pow(vels[i+1], 2) + (2 * END_ACCEL * (lengthMap[i+1] - lengthMap[i])));
Expand All @@ -90,17 +127,23 @@ std::vector<float> Pod::getVelocities(const std::vector<glm::vec3>& points) {
if (vels[i] < DEFAULT_POD_MAX_SPEED) {
count2 += 1;
} else {
count += 0;
count1 += 0;
}
}


count2 = points.size() - count2;
int start_de_accel = count2;

//convert the indices for winding up and ramping down to a point in meters on the curve
float begin_accel_distance = lengthMap[accel_upto_index];
float end_accel_distance = lengthMap[start_de_accel];
_count1 = count1;
_count2 = count2;

return vels;

}

std::vector<float> Pod::calcInitAccels(std::unordered_map<int, float>& lengthMap, const std::vector<glm::vec3>& points, float begin_accel_distance, float end_accel_distance) {

std::vector<float> accels;

//fill in the accelerations of the curve, use the centrip accel when in middle of curve
for (int i = 0; i < points.size() - 1; i++) {
Expand All @@ -114,24 +157,31 @@ std::vector<float> Pod::getVelocities(const std::vector<glm::vec3>& points) {
}
}

return accels;

// Now we need to find all the points where the acceleration is larger than "g". For now we will ignore the
// beginning and the end of the route.
}

// this is a vector of the indices in the points and accels array where the acceleration is larger than g.
std::vector<int> Pod::calcAccelsTooHigh(const std::vector<glm::vec3>& points) {
// This is a vector of the indices in the points and accels array where the acceleration is larger than g.
std::vector<int> accels_too_high;

// Now we need to find all the points where the acceleration is larger than "g". For now we will ignore the
// beginning and the end of the route.
// ignore first and last points
for (int i = accel_upto_index + 1; i < start_de_accel; i++) {
for (int i = _count1 + 1; i < _count2; i++) {
float centrip = calcCentripetalAccel(points[i - 1], points[i], points[i + 1]);
if (centrip > g) {
accels_too_high.push_back(i);
}
}

return accels_too_high;
}

std::vector<float> Pod::fixVelocities(std::vector<float> vels, std::unordered_map<int, float>& lengthMap, std::vector<int> accels_too_high, const std::vector<glm::vec3>& points) {
// Now we must go to all these points, using the velocity, and bringing it down to the velocity that it must be
// in order to make the centripetal acceleration at a good level.
for (int i = accel_upto_index + 1; i < accels_too_high.size(); i++) {
for (int i = _count1 + 1; i < accels_too_high.size(); i++) {
float radiusAtPoint = Bezier::radiusOfCurvature(points[accels_too_high[i] - 1],
points[accels_too_high[i]],
points[accels_too_high[i] + 1]);
Expand All @@ -158,25 +208,4 @@ std::vector<float> Pod::getVelocities(const std::vector<glm::vec3>& points) {
}

return vels;
}

//TODO: Account for going vertical movement
float Pod::timeForCurve(const std::vector<glm::vec3>& points) {

std::vector<float> vels = getVelocities(points);
std::unordered_map<int, float> lengthMap = Bezier::bezierLengthMap(points);

//We now calculate the time for the pod to traverse the route
float time = 0.0;
float dist = 0.0;

//Calculate times.
for (int i = 1; i < vels.size() - 1 ; i++) {
dist = lengthMap[i+1] - lengthMap[i];
time += (dist / vels[i]);
}

return time;

}

}
194 changes: 132 additions & 62 deletions src/routes-lib/pod/pod.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,68 +36,138 @@

class Pod {

public:

/**
* Creates a new Pod object with the given max speed.
*
* @param max_speed
* The max speed of the hyperloop pod in meters / second.
*/
Pod(float max_speed = DEFAULT_POD_MAX_SPEED);

/**
* Calculates the minimum radius of curvature that the track may have in meters.
* This is based on the maximum speed of the hyperloop pod in meters / second
* and a max lateral acceleration of g
*
* @return
* The minimum radius of curvature that should be allowed for human comfort on the track.
*/
float minCurveRadius() const;

/**
* Calculates the centripetal acceleration at a point in m/s^2
*
* @param p0
*
* The point before the point of interest
* @param p1
*
* The point of interest
* @param p2
* The point after the point of interest
*
* @return
* The centripetal acceleration at a point in m/s^2
*
*/
float calcCentripetalAccel(glm::vec3 p0, glm::vec3 p1, glm::vec3 p2) const;

/**
* Gets the velocities at each index along the route
*
* @return
* vector of velocities at each point in m/s
*/
std::vector<float> getVelocities(const std::vector<glm::vec3>& points);

/**
* Calculates the time to travel the route in seconds
*
* @param points
* The points of the bezier curve
*
* @return
* The time required to travel on a given hyperloop route in seconds
*/
float timeForCurve(const std::vector<glm::vec3>& points);


private:

/** The max speed in meters / second of this pod. */
float _max_speed;
public:

/**
* Creates a new Pod object with the given max speed.
*
* @param max_speed
* The max speed of the hyperloop pod in meters / second.
*/
Pod(float max_speed = DEFAULT_POD_MAX_SPEED);

/**
* Calculates the minimum radius of curvature that the track may have in meters.
* This is based on the maximum speed of the hyperloop pod in meters / second
* and a max lateral acceleration of g
*
* @return
* The minimum radius of curvature that should be allowed for human comfort on the track.
*/
float minCurveRadius() const;

/**
* Calculates the centripetal acceleration at a point in m/s^2
*
* @param p0
*
* The point before the point of interest
* @param p1
*
* The point of interest
* @param p2
* The point after the point of interest
*
* @return
* The centripetal acceleration at a point in m/s^2
*
*/
float calcCentripetalAccel(glm::vec3 p0, glm::vec3 p1, glm::vec3 p2) const;

/**
* Gets the velocities at each index along the route
*
* @return
* vector of velocities at each point in m/s
*/
std::vector<float> getVelocities(const std::vector<glm::vec3>& points);

/**
* Calculates the time to travel the route in seconds
*
* @param points
* The points of the bezier curve
*
* @return
* The time required to travel on a given hyperloop route in seconds
*/
float timeForCurve(const std::vector<glm::vec3>& points);


private:

/**
* Calculates the initial velocities along the route without accounting for accelerations
*
* @param lengthMap
* An unordered map of index in the points array to length so far along the route
*
* @param points
* The points of the bezier curve for the route
*
* @return
* The vector of velocities that have been calculated
*/
std::vector<float> calcInitVelocities(std::unordered_map<int, float>& lengthMap, const std::vector<glm::vec3>& points);

/**
* Calculate initial accelerations, which are just the centripetal accelerations so far
*
* @param lengthMap
* An unordered map of index in the points array to length so far along the route
*
* @param points
* The points of the bezier curve for the route
*
* @param begin_accel_distance
* The distance that the pod ramps up for
*
* @param end_accel_distance
* The distance that the pod starts winding down at
*
* @return
* THe vector of the initial accelerations along the route
*/
std::vector<float> calcInitAccels(std::unordered_map<int, float>& lengthMap, const std::vector<glm::vec3>& points, float begin_accel_distance, float end_accel_distance);

/**
* Calculate the indices where the centripetal acceleration is greater than g
*
* @param points
* The points of the bezier curve for the route
*
* @return
* A vector of indices where the centrip accel is greater than g along the route
*
*/
std::vector<int> calcAccelsTooHigh(const std::vector<glm::vec3>& points);

/**
* Fix velocities based off the new accelerations
*
* @param vels
* The initial velocities along the route
*
* @param lengthMap
* An unordered map of index in the points array to length so far along the route
*
* @param accels_too_high
* A vector of indices where the centrip accel is greater than g along the route
*
* @return
* The final velocities at each point
*
*/
std::vector<float> fixVelocities(std::vector<float> vels, std::unordered_map<int, float>& lengthMap, std::vector<int> accels_too_high, const std::vector<glm::vec3>& points);

/** The max speed in meters / second of this pod. */
float _max_speed;

// The index where winding up ends
int _count1;

// The index where winding down starts
int _count2;
};


Expand Down

0 comments on commit c620b94

Please sign in to comment.