hermite
0.0.1
|
Hermite is a C++ library for computing cubic Hermite splines and natural cubic splines (mainly for robotics).
Splines are parametric piecewise functions that describe an object's position given a time. A cubic spline describes this motion using a cubic polynomial function for each dimension of the position. To compute splines, it needs to be given a path. Path are given through a hermite::Pose object. A pose (for our purposes) is a data structure containing a point in time, where each pose describes the time of the pose, the position at that time, and the velocity at that time.
Cubic hermite splines allow for more local control, giving users the ability so specify both desired positions and velocities at a certain time. Changing one waypoint will only affect the curve that goes through the waypoint and will not affect other parts of the curve. However, each waypoint only offers C1 continuity, which means that only the function and the derivative are continuous at that point. This can lead to high jerk as acceleration is discontinuous, and the curve is not as smooth. On the other hand, natural cubic splines offer C2 continuity at each waypoint, meaning that the function, its derivative, and its second derivative are continuous. This not only makes the curve more smooth but also reduces the jerk as the acceleration is continuous. However, the user loses local control, as editing one waypoint will regenerate the entire curve rather than the curve around the waypoint, and the user cannot specify the velocities of the poses besides the first and the last one.
Each "piece" of a cubic hermite spline can be given by the following equation:
\[ \mathbf{p}(t) = h_{00}(t)\mathbf{p_0} + h_{10}(t)\left(x_{k+1} - x_k\right)\mathbf{m_0} + h_{01}(t)\mathbf{p_1} + h_{11}(t)\left(x_{k+1} - x_k\right)\mathbf{m_1} \]
Where:
\[ h_{00}(t)=2t^3-3t^2+1 \\ h_{10}(t)=t^3-2t^2+t \\ h_{01}(t)=-2t^3+3t^2 \\ h_{11}(t)=t^3-t^2 \]
From this, we can see that we can generate a smooth cubic spline on any arbitrary interval given the interval's starting and ending times, positions, and velocities. Since \(\mathbf{p}\) is a vector, this can be applied to any dimension, generating a smooth path not only for 1D objects but 2D and 3D as well. To generate a spline for many waypoints, we need to specify the time, position, and velocity for every waypoint.
Important things to remember for Hermite splines:
Natural cubic splines are Hermite splines, but the velocities at each waypoint are automatically determined to ensure continuous acceleration. In one dimension, each "piece" of a natural cubic spline can be described by:
\[ p(t)=a+bt+ct^2+dt^3 \\ p'(t)=b+2ct+3dt^2 \\ p''(t)=2c+6dt \]
At each waypoint, we need to make sure that \(p(t)\), \(p'(t)\), and \(p''(t)\), forming a system of equations. In order to fully solve this system of equations, the user needs to provide the time and position of each waypoint and the velocities of the first and last waypoints. This can be extended to multiple dimensions, allowing for the generation of a smooth path in 1D, 2D, and 3D.
Important things to remember for natural cubic splines:
Below gives information about usage of the library.
Install the library:
Then place the code below:
The include path will be like so:
To install locally, you can clone the repository, then copy the folders containing the source code (i.e. the include/hermite
folder) into your codebase.
The main class that is used is the hermite::Hermite class. This class acts like a std::map, where different hermite::Pose waypoint objects can be inserted and removed with logarithmic complexity. Using this class, you need to specify the multiplier for the time. The higher this multiplier, the more accurate the time is stored. However, in the case of robotics, a multiplier of 10 works as time to the first decimal digit is precise enough. Because of this, the default constructor initializes the class with a multiplier of 10. For more information about the multiplier, visit the documentation about the class, which can be accessed above.
After inserting the waypoints, you can get the position, velocity, and acceleration vectors of the path at any given time within the time interval (from the time given in the first waypoint to the time given in the last waypoint). You would do this by calling hermite::Hermite::getPos() (or hermite::Hermite::operator()()), hermite::Hermite::getVel(), and hermite::Hermite::getAcc(), respectively. These methods return an svector::Vector object.
The hermite::Hermite and hermite::Pose classes comes with a template, where you have to specify the number of dimensions of each points. For example, if you were working in a 2D space, then you would put "2" in the template. The examples below are in 1 dimension, hence the "1" in the template argument.
Example usage:
Additional utility methods can be found by visiting the class's documentation, but the ones listed above are most likely to be used on a robot.
hermite::Cubic is the main class for the use of cubic splines. It is highly recommended to manage waypoints (inserting, deleting, replacing) through the hermite::Hermite class, then using hermite::Hermite::getAllWaypoints() to feed into the constructor of hermite::Cubic. This is because the constructor of hermite::Cubic expects a vector of hermite::Pose waypoints that are sorted by time and that do not contain any repeats of times. However, to conserve memory, you can directly pass in a vector to the constructor, but you need to make sure that the waypoints in the vector are sorted by time, and there are no two waypoints that share the same time.
Unlike hermite::Hermite objects, each hermite::Cubic object can only generate a path for a unique set of waypoints. In other words, it is impossible to generate multiple paths from multiple combinations of waypoints using a single hermite::Cubic object, as you cannot insert or delete waypoints from the object. To generate a new spline for a new set of waypoints, you would need to insert points into or delete points from a hermite::Hermite object then create a new hermite::Cubic object by calling the constructor with the output of hermite::Hermite::getAllWaypoints().
The hermite::Cubic and hermite::Pose classes comes with a template, where you have to specify the number of dimensions of each points. For example, if you were working in a 2D space, then you would put "2" in the template. The examples below are in 1 dimension, hence the "1" in the template argument.
Example usage:
Additional utility methods can be found by visiting the class's documentation, but the ones listed above are most likely to be used on a robot.