@@ -51,12 +51,16 @@ class GoToPlace::Model : public Activity::Model
5151 static Activity::ConstModelPtr make (
5252 State invariant_initial_state,
5353 const Parameters& parameters,
54- const std::vector<Goal>& goal);
54+ const std::vector<Goal>& goal,
55+ const bool start_at_departure);
5556
5657 // Documentation inherited
58+ // earliest_time_constraint:
59+ // - _start_at_departure == false: earliest allowed arrival time
60+ // - _start_at_departure == true: earliest allowed departure time
5761 std::optional<Estimate> estimate_finish (
5862 State initial_state,
59- rmf_traffic::Time earliest_arrival_time ,
63+ rmf_traffic::Time earliest_time_constraint ,
6064 const Constraints& constraints,
6165 const TravelEstimator& estimator) const final ;
6266
@@ -71,18 +75,21 @@ class GoToPlace::Model : public Activity::Model
7175 Model (
7276 State invariant_finish_state,
7377 rmf_traffic::Duration invariant_duration,
74- Goal goal);
78+ Goal goal,
79+ const bool start_at_departure);
7580
7681 State _invariant_finish_state;
7782 rmf_traffic::Duration _invariant_duration;
7883 Goal _goal;
84+ const bool _start_at_departure;
7985};
8086
8187// ==============================================================================
8288Activity::ConstModelPtr GoToPlace::Model::make (
8389 State invariant_initial_state,
8490 const Parameters& parameters,
85- const std::vector<Goal>& goals)
91+ const std::vector<Goal>& goals,
92+ const bool start_at_departure)
8693{
8794 if (goals.empty ())
8895 {
@@ -129,13 +136,14 @@ Activity::ConstModelPtr GoToPlace::Model::make(
129136 new Model (
130137 std::move (invariant_finish_state),
131138 shortest_travel_time.value_or (rmf_traffic::Duration (0 )),
132- std::move (selected_goal)));
139+ std::move (selected_goal),
140+ start_at_departure));
133141}
134142
135143// ==============================================================================
136144std::optional<Estimate> GoToPlace::Model::estimate_finish (
137145 State initial_state,
138- rmf_traffic::Time earliest_arrival_time ,
146+ rmf_traffic::Time earliest_time_constraint ,
139147 const Constraints& constraints,
140148 const TravelEstimator& travel_estimator) const
141149{
@@ -149,13 +157,28 @@ std::optional<Estimate> GoToPlace::Model::estimate_finish(
149157 if (!travel.has_value ())
150158 return std::nullopt ;
151159
152- const auto arrival_time =
153- std::max (
154- initial_state.time ().value () + travel->duration (),
155- earliest_arrival_time);
160+ rmf_traffic::Time wait_until_time;
156161
157- const auto wait_until_time = arrival_time - travel->duration ();
158- finish.time (wait_until_time + travel->duration ());
162+ if (_start_at_departure)
163+ {
164+ // Event starts at 'departure'. The constraint applies to 'departure'.
165+ const auto departure_time =
166+ std::max (
167+ initial_state.time ().value (),
168+ earliest_time_constraint);
169+ wait_until_time = departure_time;
170+ finish.time (departure_time + travel->duration ());
171+ }
172+ else
173+ {
174+ // Event starts at 'arrival'. The constraint applies to 'arrival'.
175+ const auto arrival_time =
176+ std::max (
177+ initial_state.time ().value () + travel->duration (),
178+ earliest_time_constraint);
179+ wait_until_time = arrival_time - travel->duration ();
180+ finish.time (arrival_time);
181+ }
159182
160183 if (constraints.drain_battery ())
161184 {
@@ -192,10 +215,12 @@ State GoToPlace::Model::invariant_finish_state() const
192215GoToPlace::Model::Model (
193216 State invariant_finish_state,
194217 rmf_traffic::Duration invariant_duration,
195- Goal goal)
218+ Goal goal,
219+ const bool start_at_departure)
196220: _invariant_finish_state(std::move(invariant_finish_state)),
197221 _invariant_duration (invariant_duration),
198- _goal(std::move(goal))
222+ _goal(std::move(goal)),
223+ _start_at_departure(start_at_departure)
199224{
200225 // Do nothing
201226}
@@ -207,6 +232,7 @@ class GoToPlace::Description::Implementation
207232 std::vector<rmf_traffic::agv::Plan::Goal> one_of;
208233 std::vector<rmf_traffic::agv::Plan::Goal> expected_next_destinations;
209234 bool prefer_same_map = false ;
235+ bool start_at_departure = false ;
210236};
211237
212238// ==============================================================================
@@ -248,15 +274,17 @@ Activity::ConstModelPtr GoToPlace::Description::make_model(
248274 goals.push_back (g);
249275 }
250276
251- const auto model = Model::make (invariant_initial_state, parameters, goals);
277+ const auto model = Model::make (
278+ invariant_initial_state, parameters, goals, _pimpl->start_at_departure );
252279 if (model)
253280 return model;
254281 }
255282
256283 return Model::make (
257284 std::move (invariant_initial_state),
258285 parameters,
259- _pimpl->one_of );
286+ _pimpl->one_of ,
287+ _pimpl->start_at_departure );
260288}
261289
262290// ==============================================================================
@@ -418,11 +446,24 @@ auto GoToPlace::Description::prefer_same_map(bool choice) -> Description&
418446 return *this ;
419447}
420448
449+ // ==============================================================================
450+ bool GoToPlace::Description::start_at_departure () const
451+ {
452+ return _pimpl->start_at_departure ;
453+ }
454+
455+ // ==============================================================================
456+ auto GoToPlace::Description::start_at_departure (bool choice) -> Description&
457+ {
458+ _pimpl->start_at_departure = choice;
459+ return *this ;
460+ }
461+
421462// ==============================================================================
422463GoToPlace::Description::Description ()
423464{
424465 // Do nothing
425466}
426467
427468} // namespace phases
428- } // namespace rmf_task_sequence
469+ } // namespace rmf_task_sequence
0 commit comments