44 #include <ilqgames/dynamics/multi_player_integrable_system.h> 45 #include <ilqgames/utils/operating_point.h> 46 #include <ilqgames/utils/strategy.h> 47 #include <ilqgames/utils/types.h> 53 bool MultiPlayerIntegrableSystem::integrate_using_euler_ =
false;
55 VectorXf MultiPlayerIntegrableSystem::Integrate(
56 Time t0, Time t,
const VectorXf& x0,
const OperatingPoint& operating_point,
57 const std::vector<Strategy>& strategies)
const {
59 CHECK_GE(t0, operating_point.t0);
60 CHECK_EQ(strategies.size(), NumPlayers());
62 std::vector<VectorXf> us(NumPlayers());
65 const Time relative_t0 = t0 - operating_point.t0;
66 const size_t current_timestep =
67 static_cast<size_t>(relative_t0 / time::kTimeStep);
69 const Time relative_t = t - operating_point.t0;
70 const size_t final_timestep =
71 static_cast<size_t>(relative_t / time::kTimeStep);
76 if (t0 > operating_point.t0)
77 x = IntegrateToNextTimeStep(t0, x0, operating_point, strategies);
80 x = Integrate(current_timestep + 1, final_timestep, x, operating_point,
84 return IntegrateFromPriorTimeStep(t, x, operating_point, strategies);
87 VectorXf MultiPlayerIntegrableSystem::Integrate(
88 size_t initial_timestep,
size_t final_timestep,
const VectorXf& x0,
89 const OperatingPoint& operating_point,
90 const std::vector<Strategy>& strategies)
const {
92 std::vector<VectorXf> us(NumPlayers());
93 for (
size_t kk = initial_timestep; kk < final_timestep; kk++) {
94 const Time t = operating_point.t0 + kk * time::kTimeStep;
97 for (PlayerIndex ii = 0; ii < NumPlayers(); ii++)
98 us[ii] = strategies[ii](kk, x - operating_point.xs[kk],
99 operating_point.us[kk][ii]);
101 x = Integrate(t, time::kTimeStep, x, us);
107 VectorXf MultiPlayerIntegrableSystem::IntegrateToNextTimeStep(
108 Time t0,
const VectorXf& x0,
const OperatingPoint& operating_point,
109 const std::vector<Strategy>& strategies)
const {
110 CHECK_GE(t0, operating_point.t0);
113 const Time relative_t0 = t0 - operating_point.t0;
114 const size_t current_timestep =
static_cast<size_t>(
116 constants::kSmallNumber)
118 const Time remaining_time_this_step =
119 time::kTimeStep * (current_timestep + 1) - relative_t0;
120 CHECK_LT(remaining_time_this_step, time::kTimeStep + constants::kSmallNumber);
121 CHECK_LT(current_timestep, operating_point.xs.size());
124 const float frac = remaining_time_this_step / time::kTimeStep;
125 const VectorXf x0_ref =
126 (current_timestep + 1 < operating_point.xs.size())
127 ? frac * operating_point.xs[current_timestep] +
128 (1.0 - frac) * operating_point.xs[current_timestep + 1]
129 : operating_point.xs.back();
132 std::vector<VectorXf> us(NumPlayers());
133 for (PlayerIndex ii = 0; ii < NumPlayers(); ii++)
134 us[ii] = strategies[ii](current_timestep, x0 - x0_ref,
135 operating_point.us[current_timestep][ii]);
137 return Integrate(t0, remaining_time_this_step, x0, us);
140 VectorXf MultiPlayerIntegrableSystem::IntegrateFromPriorTimeStep(
141 Time t,
const VectorXf& x0,
const OperatingPoint& operating_point,
142 const std::vector<Strategy>& strategies)
const {
144 const Time relative_t = t - operating_point.t0;
145 const size_t current_timestep =
146 static_cast<size_t>(relative_t / time::kTimeStep);
147 const Time remaining_time_until_t =
148 relative_t - time::kTimeStep * current_timestep;
149 CHECK_LT(current_timestep, operating_point.xs.size()) << t;
150 CHECK_LT(remaining_time_until_t, time::kTimeStep);
153 std::vector<VectorXf> us(NumPlayers());
154 for (PlayerIndex ii = 0; ii < NumPlayers(); ii++) {
155 us[ii] = strategies[ii](current_timestep,
156 x0 - operating_point.xs[current_timestep],
157 operating_point.us[current_timestep][ii]);
160 return Integrate(operating_point.t0 + time::kTimeStep * current_timestep,
161 remaining_time_until_t, x0, us);
164 VectorXf MultiPlayerIntegrableSystem::Integrate(
165 Time t0, Time time_interval,
const Eigen::Ref<VectorXf>& x0,
166 const std::vector<Eigen::Ref<VectorXf>>& us)
const {
167 std::vector<VectorXf> eval_us(us.size());
168 std::transform(us.begin(), us.end(), eval_us.begin(),
169 [](
const Eigen::Ref<VectorXf>& u) {
return u.eval(); });
171 return Integrate(t0, time_interval, x0.eval(), eval_us);