void runge_kutta4_integrate_impl( const StateSpace& space, const StateSpaceSystem& sys, const typename pp::topology_traits<StateSpace>::point_type& start_point, typename pp::topology_traits<StateSpace>::point_type& end_point, const InputTrajectory& u_traj, double start_time, double end_time, double time_step) { typedef typename pp::topology_traits<StateSpace>::point_type PointType; typedef typename pp::topology_traits<StateSpace>::point_difference_type PointDiffType; typedef typename pp::spatial_trajectory_traits<InputTrajectory>::const_waypoint_descriptor InputWaypoint; typedef typename pp::spatial_trajectory_traits<InputTrajectory>::point_type InputType; std::pair< InputWaypoint, InputType> u_wp = u_traj.get_waypoint_at_time(start_time); PointDiffType dp = sys.get_state_derivative(space, start_point, u_wp.second.pt, start_time); double t = start_time; end_point = start_point; while(((time_step > 0.0) && (t < end_time)) || ((time_step < 0.0) && (t > end_time))) { PointType w = end_point; PointDiffType k1 = time_step * dp; end_point = space.adjust(end_point, 0.5 * k1); t += time_step * 0.5; u_wp = u_traj.move_time_diff_from(u_wp, 0.5 * time_step); dp = sys.get_state_derivative(space, end_point, u_wp.second.pt, t); PointDiffType k2 = time_step * dp; end_point = space.adjust(w, 0.5 * k2); dp = sys.get_state_derivative(space, end_point, u_wp.second.pt, t); PointDiffType k3 = time_step * dp; end_point = space.adjust(w, k3); t += time_step * 0.5; u_wp = u_traj.move_time_diff_from(u_wp, 0.5 * time_step); dp = sys.get_state_derivative(space, end_point, u_wp.second.pt, t); end_point = space.adjust(end_point, (1.0 / 6.0) * k1 + (2.0 / 6.0) * k2 + (time_step / 6.0) * dp - (2.0/3.0) * k3); dp = sys.get_state_derivative(space, end_point, u_wp.second.pt, t); }; };
void dormand_prince45_integrate_impl( const StateSpace& space, const StateSpaceSystem& sys, const typename pp::topology_traits<StateSpace>::point_type& start_point, typename pp::topology_traits<StateSpace>::point_type& end_point, const InputTrajectory& u_traj, double start_time, double end_time, double time_step, double tolerance, double min_step, double max_step) { using std::fabs; using std::pow; using ReaK::to_vect; typedef typename pp::topology_traits<StateSpace>::point_type PointType; typedef typename pp::topology_traits<StateSpace>::point_difference_type PointDiffType; if ((time_step == 0.0) || ((time_step > 0.0) && (start_time > end_time)) || ((time_step < 0.0) && (end_time > start_time)) || (tolerance <= 0.0) || (min_step > max_step)) throw impossible_integration(start_time, end_time, time_step); typedef typename pp::spatial_trajectory_traits<InputTrajectory>::const_waypoint_descriptor InputWaypoint; typedef typename pp::spatial_trajectory_traits<InputTrajectory>::point_type InputType; std::pair< InputWaypoint, InputType> u_wp = u_traj.get_waypoint_at_time(start_time); PointDiffType dp = sys.get_state_derivative(space, start_point, u_wp.second.pt, start_time); double t = start_time; end_point = start_point; while(((time_step > 0.0) && (t < end_time)) || ((time_step < 0.0) && (t > end_time))) { PointType prevY = end_point; PointDiffType k1 = time_step * dp; end_point = space.adjust(end_point, 0.2 * k1); t += time_step / 5.0; u_wp = u_traj.move_time_diff_from(u_wp, time_step / 5.0); dp = sys.get_state_derivative(space, end_point, u_wp.second.pt, t); PointDiffType k2 = time_step * dp; end_point = space.adjust(prevY, (3.0 / 40.0) * k1 + (9.0 / 40.0) * k2); t += time_step / 10.0; u_wp = u_traj.move_time_diff_from(u_wp, time_step / 10.0); dp = sys.get_state_derivative(space, end_point, u_wp.second.pt, t); PointDiffType k3 = time_step * dp; end_point = space.adjust(prevY, (44.0 / 45.0) * k1 - (56.0 / 15.0) * k2 + (32.0 / 9.0) * k3); t += time_step / 2.0; u_wp = u_traj.move_time_diff_from(u_wp, time_step / 2.0); dp = sys.get_state_derivative(space, end_point, u_wp.second.pt, t); PointDiffType k4 = time_step * dp; end_point = space.adjust(prevY, (19372.0 / 6561.0) * k1 - (25360.0 / 2187.0) * k2 + (64448.0 / 6561.0) * k3 - (212.0 / 729.0) * k4); t += 4.0 * time_step / 45.0; u_wp = u_traj.move_time_diff_from(u_wp, 4.0 * time_step / 45.0); dp = sys.get_state_derivative(space, end_point, u_wp.second.pt, t); PointDiffType k5 = time_step * dp; end_point = space.adjust(prevY, (9017.0 / 3168.0) * k1 - (355.0 / 33.0) * k2 - (46732.0 / 5247.0) * k3 + (49.0 / 176.0) * k4 - (5103.0 / 18656.0) * k5); t += time_step / 9.0; u_wp = u_traj.move_time_diff_from(u_wp, time_step / 9.0); dp = sys.get_state_derivative(space, end_point, u_wp.second.pt, t); PointDiffType k6 = time_step * dp; end_point = space.adjust(prevY, (35.0 / 384.0) * k1 + (500.0 / 1113.0) * k3 + (125.0 / 192.0) * k4 - (2187.0 / 6784.0) * k5 + (11.0 / 84.0) * k6); dp = sys.get_state_derivative(space, end_point, u_wp.second.pt, t); PointDiffType k7 = time_step * dp; vect_n<double> err_vect = to_vect<double>((5170.0 / 57600.0) * k1 + (7571.0 / 16695.0) * k3 + (393.0 / 640.0) * k4 - (92097.0 / 339200.0) * k5 + (187.0 / 2100.0) * k6 - (39.0 / 40.0) * k7); double Rmax = 0.0; std::size_t worst_DOF = 0; for(std::size_t i = 0; i < err_vect.size(); ++i) { double R = fabs(err_vect[i] / time_step); if(R > Rmax) { Rmax = R; worst_DOF = i; }; }; if(Rmax > tolerance) { if(fabs(time_step) <= min_step) throw untolerable_integration(tolerance, Rmax, worst_DOF, time_step, t); t -= time_step; u_wp = u_traj.move_time_diff_from(u_wp, -time_step); end_point = prevY; dp = sys.get_state_derivative(space, end_point, u_wp.second.pt, t); double R = 0.84 * pow(tolerance / Rmax, 0.25); if(R < 0.1) time_step *= 0.1; else time_step *= R; } else { end_point = space.adjust(prevY, (5170.0 / 57600.0) * k1 + (7571.0 / 16695.0) * k3 + (393.0 / 640.0) * k4 - (92097.0 / 339200.0) * k5 + (187.0 / 2100.0) * k6 + (1.0 / 40.0) * k7); dp = sys.get_state_derivative(space, end_point, u_wp.second.pt, t); double R = 0.84 * pow(tolerance / Rmax, 0.25); if(R >= 4.0) time_step *= 4.0; else if(R > 1.0) time_step *= R; //if(((time_step > 0.0) && (t + time_step > end_time)) || ((time_step < 0.0) && (t + time_step < end_time))) //time_step = end_time - t; }; if(fabs(time_step) < min_step) time_step *= fabs(min_step / time_step); if(fabs(time_step) > max_step) time_step *= fabs(max_step / time_step); }; };
void hamming_mod_integrate_impl( const StateSpace& space, const StateSpaceSystem& sys, const typename pp::topology_traits<StateSpace>::point_type& start_point, typename pp::topology_traits<StateSpace>::point_type& end_point, const InputTrajectory& u_traj, double start_time, double end_time, double time_step) { if ((time_step == 0.0) || ((time_step > 0.0) && (start_time > end_time)) || ((time_step < 0.0) && (start_time < end_time))) throw impossible_integration(start_time, end_time, time_step); typedef typename pp::topology_traits<StateSpace>::point_type PointType; typedef typename pp::topology_traits<StateSpace>::point_difference_type PointDiffType; typedef typename pp::spatial_trajectory_traits<InputTrajectory>::const_waypoint_descriptor InputWaypoint; typedef typename pp::spatial_trajectory_traits<InputTrajectory>::point_type InputType; std::pair< InputWaypoint, InputType> u_wp = u_traj.get_waypoint_at_time(start_time); double back_time = start_time; PointDiffType dp = sys.get_state_derivative(space, start_point, u_wp.second.pt, start_time); PointType w = start_point; PointType Y_n[3]; PointDiffType Yp_n[3]; for(std::size_t i = 0; i < 3; ++i) { PointDiffType k1 = time_step * dp; Y_n[i] = space.adjust(w, -0.25 * k1); back_time -= time_step * 0.25; u_wp = u_traj.move_time_diff_from(u_wp, -0.25 * time_step); Yp_n[i] = sys.get_state_derivative(space, Y_n[i], u_wp.second.pt, back_time); PointDiffType k2 = time_step * Yp_n_1; Y_n[i] = space.adjust(Y_n[i], (5.0 / 32.0) * k1 - (9.0 / 32.0) * k2); back_time -= time_step * 0.125; u_wp = u_traj.move_time_diff_from(u_wp, -0.125 * time_step); Yp_n[i] = sys.get_state_derivative(space, Y_n[i], u_wp.second.pt, back_time); PointDiffType k3 = time_step * Yp_n[i]; Y_n[i] = space.adjust(Y_n[i], (1250865.0 / 351520.0) * k2 - (276165.0 / 351520.0) * k1 - (1167360.0 / 351520.0) * k3); back_time -= 57.0 * time_step / 104.0; u_wp = u_traj.move_time_diff_from(u_wp, -57.0 / 104.0 * time_step); Yp_n[i] = sys.get_state_derivative(space, Y_n[i], u_wp.second.pt, back_time); PointDiffType k4 = time_step * Yp_n[i]; Y_n[i] = space.adjust(w, 8.0 * k2 - (439.0 / 216.0) * k1 - (3680.0 / 513.0) * k3 + (845.0 / 4104.0) * k4); back_time -= time_step / 13.0; u_wp = u_traj.move_time_diff_from(u_wp, -time_step / 13.0); Yp_n[i] = sys.get_state_derivative(space, Y_n[i], u_wp.second.pt, back_time); PointDiffType k5 = time_step * Yp_n[i]; Y_n[i] = space.adjust(w, (8.0 / 27.0) * k1 - 2.0 * k2 + (3544.0 / 2565.0) * k3 - (1859.0 / 4104.0) * k4 + (11.0 / 40.0) * k5); back_time += time_step * 0.5; u_wp = u_traj.move_time_diff_from(u_wp, 0.5 * time_step); Yp_n[i] = sys.get_state_derivative(space, Y_n[i], u_wp.second.pt, back_time); Y_n[i] = space.adjust(w, (-16.0 / 135.0) * k1 - (6656.0 / 12825.0) * k3 - (28561.0 / 56430.0) * k4 + (9.0 / 50.0) * k5 - (2.0 * time_step / 55.0) * Yp_n[i]); back_time -= time_step * 0.5; u_wp = u_traj.move_time_diff_from(u_wp, -0.5 * time_step); Yp_n[i] = sys.get_state_derivative(space, Y_n[i], u_wp.second.pt, back_time); w = Y_n[i]; dp = Yp_n[i]; }; PointType C = start_point; PointType P_n = start_point; // this makes sure the initial error sweep is zero. double t = start_time; end_point = start_point; u_wp = u_traj.get_waypoint_at_time(t); dp = sys.get_state_derivative(space, end_point, u_wp.second.pt, t); while(((time_step > 0.0) && (t < end_time)) || ((time_step < 0.0) && (t > end_time))) { PointType P = space.adjust(Y_n[2], (time_step * 4.0 / 3.0) * (2.0 * (dp + Yp_n[1]) - Yp_n[0])); PointType M = space.adjust(P, (112.0 / 121.0) * space.difference(C, P_n)); t += time_step; u_wp = u_traj.move_time_diff_from(u_wp, time_step); PointDiffType Mp = sys.get_state_derivative(space, M, u_wp.second.pt, t); C = space.adjust(end_point, 0.125 * space.difference(end_point, Y_n[1]) + (time_step * 3.0 / 8.0) * (Mp + 2.0 * dp - Yp_n[0])); Y_n[2] = Y_n[1]; Y_n[1] = Y_n[0]; Y_n[0] = end_point; end_point = space.adjust(C, (9.0 / 121.0) * space.difference(P, C)); P_n = P; Yp_n[1] = Yp_n[0]; Yp_n[0] = dp; dp = sys.get_state_derivative(space, end_point, u_wp.second.pt, t); }; };