Skip to content
This repository was archived by the owner on Jul 22, 2021. It is now read-only.

Commit e8dc70b

Browse files
arjo129mxgrey
andauthored
Add persistence to Traffic Schedule Participant IDs (#242)
Signed-off-by: Michael X. Grey <[email protected]> Co-authored-by: Arjo Chakravarty <[email protected]> Co-authored-by: Michael X. Grey <[email protected]>
1 parent 308264c commit e8dc70b

File tree

27 files changed

+1382
-62
lines changed

27 files changed

+1382
-62
lines changed

rmf_fleet_adapter/rmf_rxcpp/examples/PlanPath.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ struct MetaPlannerAction
295295
rmf_traffic::schedule::ItineraryVersion v = 0;
296296
rmf_traffic::schedule::Version r = 0;
297297
for (const auto& route : alternative)
298-
database.extend(p, {{r, route}}, v++);
298+
database.extend(p.id(), {{r, route}}, v++);
299299

300300
planner_actions.emplace_back(std::make_shared<PlannerAction>(
301301
std::move(database), config, start_B, goal_B, sync_failure));

rmf_traffic/CHANGELOG.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
Changelog for package rmf_traffic
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44

5+
1.3.0 (2021-XX-XX)
6+
------------------
7+
* Add persistence to Traffic Schedule Participant IDs: [#242](https://github.com/osrf/rmf_core/pull/242)
8+
59
1.2.0 (2021-01-05)
610
------------------
711
* Improve planner performance scaling for large graphs: [#243](https://github.com/osrf/rmf_core/pull/243)

rmf_traffic/include/rmf_traffic/schedule/Database.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class Database :
8181
ItineraryVersion version) final;
8282

8383
// Documentation inherited from Writer
84-
ParticipantId register_participant(
84+
Registration register_participant(
8585
ParticipantDescription participant_info) final;
8686

8787
/// Before calling this function on a Database, you should set the current
@@ -199,11 +199,16 @@ class Database :
199199
/// call this function for any other purpose.
200200
void set_current_time(Time time);
201201

202-
/// Get the curret itinerary version for the specified participant.
202+
/// Get the current itinerary version for the specified participant.
203203
//
204204
// TODO(MXG): This function needs unit testing
205205
ItineraryVersion itinerary_version(ParticipantId participant) const;
206206

207+
/// Get the last Route ID used by this participant.
208+
//
209+
// TODO(MXG): This function needs unit testing
210+
RouteId last_route_id(ParticipantId participant) const;
211+
207212
class Implementation;
208213
class Debug;
209214
private:

rmf_traffic/include/rmf_traffic/schedule/Writer.hpp

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,50 @@ class Writer
122122
const std::vector<RouteId>& routes,
123123
ItineraryVersion version) = 0;
124124

125-
// TODO(MXG): Consider saying "add" instead of "register" and "remove" instead
126-
// of "unregister".
125+
/// Information resulting from registering a participant
126+
class Registration
127+
{
128+
public:
129+
130+
/// Constructor
131+
///
132+
/// \param[in] id
133+
/// The ID for the registered participant
134+
///
135+
/// \param[in] version
136+
/// The last itinerary version for the registered participant
137+
///
138+
/// \param[in] route_id
139+
/// The last route_id for the registered participant
140+
Registration(
141+
ParticipantId id,
142+
ItineraryVersion version,
143+
RouteId route_id);
144+
145+
/// The ID of the registered participant
146+
ParticipantId id() const;
147+
148+
/// The last itinerary version of the registered participant. New
149+
/// Participants will begin by adding up from this version when issuing
150+
/// schedule updates.
151+
///
152+
/// This value might vary for systems that enforce participant uniqueness.
153+
/// If this participant was registered in the past and is now being
154+
/// re-registered, then the version number will pick up where it previously
155+
/// left off.
156+
ItineraryVersion last_itinerary_version() const;
157+
158+
/// The last Route ID of the registered participant. New Participants will
159+
/// begin by adding up from this Route ID when issuing new schedule updates.
160+
///
161+
/// Similar to last_itinerary_version, this value might vary for systems
162+
/// that enforce participant uniqueness.
163+
RouteId last_route_id() const;
164+
165+
class Implementation;
166+
private:
167+
rmf_utils::impl_ptr<Implementation> _pimpl;
168+
};
127169

128170
/// Register a new participant.
129171
///
@@ -134,7 +176,7 @@ class Writer
134176
/// The time at which the registration is being requested.
135177
///
136178
/// \return result of registering the new participant.
137-
virtual ParticipantId register_participant(
179+
virtual Registration register_participant(
138180
ParticipantDescription participant_info) = 0;
139181

140182
/// Unregister an existing participant.

rmf_traffic/src/rmf_traffic/schedule/Database.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ class Database::Implementation
112112
ParticipantStorage storage;
113113
const std::shared_ptr<const ParticipantDescription> description;
114114
const Version initial_schedule_version;
115+
RouteId last_route_id = std::numeric_limits<RouteId>::max();
115116
};
116117
using ParticipantStates = std::unordered_map<ParticipantId, ParticipantState>;
117118
ParticipantStates states;
@@ -231,6 +232,9 @@ class Database::Implementation
231232
{
232233
const auto& item = input[i];
233234
const RouteId route_id = item.id;
235+
if (rmf_utils::modular(state.last_route_id).less_than(route_id))
236+
state.last_route_id = route_id;
237+
234238
state.active_routes.insert(route_id);
235239

236240
RouteStorage& entry_storage = *entries[i];
@@ -628,7 +632,7 @@ void Database::erase(
628632
}
629633

630634
//==============================================================================
631-
ParticipantId Database::register_participant(
635+
Writer::Registration Database::register_participant(
632636
ParticipantDescription description)
633637
{
634638
const ParticipantId id = _pimpl->get_next_participant_id();
@@ -640,7 +644,7 @@ ParticipantId Database::register_participant(
640644
const auto description_ptr =
641645
std::make_shared<ParticipantDescription>(std::move(description));
642646

643-
_pimpl->states.insert(
647+
const auto p_it = _pimpl->states.insert(
644648
std::make_pair(
645649
id,
646650
Implementation::ParticipantState{
@@ -649,12 +653,15 @@ ParticipantId Database::register_participant(
649653
{},
650654
description_ptr,
651655
version
652-
}));
656+
})).first;
653657

654658
_pimpl->descriptions.insert({id, description_ptr});
655659

656660
_pimpl->add_participant_version[version] = id;
657-
return id;
661+
662+
const auto& state = p_it->second;
663+
return Registration(
664+
id, state.tracker->last_known_version(), state.last_route_id);
658665
}
659666

660667
//==============================================================================
@@ -1245,5 +1252,19 @@ ItineraryVersion Database::itinerary_version(ParticipantId participant) const
12451252
return p_it->second.tracker->last_known_version();
12461253
}
12471254

1255+
//==============================================================================
1256+
RouteId Database::last_route_id(ParticipantId participant) const
1257+
{
1258+
const auto p_it = _pimpl->states.find(participant);
1259+
if (p_it == _pimpl->states.end())
1260+
{
1261+
throw std::runtime_error(
1262+
"[Database::last_route_id] No participant with ID ["
1263+
+ std::to_string(participant) + "]");
1264+
}
1265+
1266+
return p_it->second.last_route_id;
1267+
}
1268+
12481269
} // namespace schedule
12491270
} // namespace rmf_traffic

rmf_traffic/src/rmf_traffic/schedule/Participant.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "debug_Participant.hpp"
2020
#include "RectifierInternal.hpp"
2121

22+
#include <sstream>
23+
2224
namespace rmf_traffic {
2325
namespace schedule {
2426

@@ -34,17 +36,17 @@ Participant Participant::Implementation::make(
3436
std::shared_ptr<Writer> writer,
3537
std::shared_ptr<RectificationRequesterFactory> rectifier_factory)
3638
{
37-
const ParticipantId id = writer->register_participant(description);
39+
const auto registration = writer->register_participant(description);
3840

3941
Participant participant;
4042
participant._pimpl = rmf_utils::make_unique_impl<Implementation>(
41-
id, std::move(description), std::move(writer));
43+
registration, std::move(description), std::move(writer));
4244

4345
if (rectifier_factory)
4446
{
4547
participant._pimpl->_rectification =
4648
rectifier_factory->make(
47-
Rectifier::Implementation::make(*participant._pimpl), id);
49+
Rectifier::Implementation::make(*participant._pimpl), registration.id());
4850
}
4951

5052
return participant;
@@ -55,6 +57,19 @@ void Participant::Implementation::retransmit(
5557
const std::vector<Rectifier::Range>& ranges,
5658
const ItineraryVersion last_known_version)
5759
{
60+
if (rmf_utils::modular(current_version()).less_than(last_known_version))
61+
{
62+
std::stringstream str;
63+
str << "[Participant::Implementation::retransmit] Remote database has a "
64+
<< "higher version number [" << last_known_version << "] than ["
65+
<< current_version() << "] the version number of the local "
66+
<< "participant [" << _id << ":" << _description.owner() << "/"
67+
<< _description.name() << "]. This indicates that the remote database "
68+
<< "is receiving participant updates from a conflicting source.";
69+
70+
throw std::runtime_error(str.str());
71+
}
72+
5873
for (const auto& range : ranges)
5974
{
6075
assert(rmf_utils::modular(range.lower).less_than_or_equal(range.upper));
@@ -97,10 +112,12 @@ ItineraryVersion Participant::Implementation::current_version() const
97112

98113
//==============================================================================
99114
Participant::Implementation::Implementation(
100-
ParticipantId id,
115+
const Writer::Registration& registration,
101116
ParticipantDescription description,
102117
std::shared_ptr<Writer> writer)
103-
: _id(id),
118+
: _id(registration.id()),
119+
_version(registration.last_itinerary_version()),
120+
_last_route_id(registration.last_route_id()),
104121
_description(std::move(description)),
105122
_writer(writer)
106123
{

rmf_traffic/src/rmf_traffic/schedule/ParticipantInternal.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class Participant::Implementation
4646
// Note: It would be better if this constructor were private, but we need to
4747
// make it public so it can be used by rmf_utils::make_unique_impl
4848
Implementation(
49-
ParticipantId id,
49+
const Writer::Registration& registration,
5050
ParticipantDescription description,
5151
std::shared_ptr<Writer> writer);
5252

@@ -59,6 +59,8 @@ class Participant::Implementation
5959
ItineraryVersion get_next_version();
6060

6161
const ParticipantId _id;
62+
ItineraryVersion _version;
63+
RouteId _last_route_id;
6264
const ParticipantDescription _description;
6365
std::shared_ptr<Writer> _writer;
6466
std::unique_ptr<RectificationRequester> _rectification;
@@ -69,8 +71,6 @@ class Participant::Implementation
6971
Writer::Input _current_itinerary;
7072

7173
ChangeHistory _change_history;
72-
RouteId _last_route_id = std::numeric_limits<RouteId>::max();
73-
ItineraryVersion _version = std::numeric_limits<ItineraryVersion>::max();
7474
rmf_traffic::Duration _cumulative_delay = std::chrono::seconds(0);
7575
};
7676

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (C) 2021 Open Source Robotics Foundation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
#include <rmf_traffic/schedule/Writer.hpp>
19+
20+
namespace rmf_traffic {
21+
namespace schedule {
22+
23+
//==============================================================================
24+
class Writer::Registration::Implementation
25+
{
26+
public:
27+
28+
ParticipantId id;
29+
ItineraryVersion version;
30+
RouteId route_id;
31+
32+
};
33+
34+
//==============================================================================
35+
Writer::Registration::Registration(
36+
ParticipantId id,
37+
ItineraryVersion version,
38+
RouteId route_id)
39+
: _pimpl(rmf_utils::make_impl<Implementation>(
40+
Implementation{id, version, route_id}))
41+
{
42+
// Do nothing
43+
}
44+
45+
//==============================================================================
46+
ParticipantId Writer::Registration::id() const
47+
{
48+
return _pimpl->id;
49+
}
50+
51+
//==============================================================================
52+
ItineraryVersion Writer::Registration::last_itinerary_version() const
53+
{
54+
return _pimpl->version;
55+
}
56+
57+
//==============================================================================
58+
RouteId Writer::Registration::last_route_id() const
59+
{
60+
return _pimpl->route_id;
61+
}
62+
63+
} // namespace schedule
64+
} // namespace rmf_traffic

rmf_traffic/test/unit/agv/test_Planner.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ rmf_traffic::Trajectory test_with_obstacle(
117117
const rmf_traffic::Profile profile = create_test_profile(UnitCircle);
118118

119119
rmf_traffic::Trajectory t_obs;
120-
const rmf_traffic::schedule::ParticipantId p_obs =
120+
const auto p_obs =
121121
database.register_participant(
122122
rmf_traffic::schedule::ParticipantDescription{
123123
"obstacle",
@@ -131,7 +131,7 @@ rmf_traffic::Trajectory test_with_obstacle(
131131
for (const auto& obstacle : obstacles)
132132
{
133133
const auto r = std::make_shared<rmf_traffic::Route>("test_map", obstacle);
134-
database.extend(p_obs, {{rid++, r}}, iv++);
134+
database.extend(p_obs.id(), {{rid++, r}}, iv++);
135135
}
136136

137137
rmf_utils::optional<rmf_traffic::agv::Planner::Result> result;
@@ -2214,7 +2214,7 @@ SCENARIO("Test planner with various start conditions")
22142214
profile};
22152215

22162216
rmf_traffic::schedule::Database database;
2217-
const rmf_traffic::schedule::ParticipantId p_obs =
2217+
const auto p_obs =
22182218
database.register_participant(
22192219
rmf_traffic::schedule::ParticipantDescription{
22202220
"obstacles",
@@ -2457,7 +2457,7 @@ SCENARIO("Test planner with various start conditions")
24572457
{
24582458
const auto r = std::make_shared<rmf_traffic::Route>(
24592459
"test_map", obstacle);
2460-
database.extend(p_obs, {{ri_o++, r}}, iv_o++);
2460+
database.extend(p_obs.id(), {{ri_o++, r}}, iv_o++);
24612461
}
24622462

24632463
const auto result1 = plan.replan(start1);

0 commit comments

Comments
 (0)