Merge lp:~ssweeny/location-service/fix-lp1570878 into lp:location-service/trunk

Proposed by Scott Sweeny
Status: Merged
Approved by: Thomas Voß
Approved revision: 252
Merged at revision: 256
Proposed branch: lp:~ssweeny/location-service/fix-lp1570878
Merge into: lp:location-service/trunk
Diff against target: 162 lines (+55/-15)
6 files modified
include/location_service/com/ubuntu/location/fusion_provider.h (+1/-1)
include/location_service/com/ubuntu/location/newer_or_more_accurate_update_selector.h (+11/-6)
include/location_service/com/ubuntu/location/newer_update_selector.h (+2/-2)
include/location_service/com/ubuntu/location/update_selector.h (+6/-2)
src/location_service/com/ubuntu/location/fusion_provider.cpp (+5/-4)
tests/provider_test.cpp (+30/-0)
To merge this branch: bzr merge lp:~ssweeny/location-service/fix-lp1570878
Reviewer Review Type Date Requested Status
Thomas Voß (community) Approve
Jim Hodapp (community) code Approve
PS Jenkins bot continuous-integration Pending
Review via email: mp+296806@code.launchpad.net

Commit message

Fusion provider: Always use an update that came from the same source as the previous used update (fixes LP: #1570878)

Description of the change

Fix a bug in the fusion provider in which it is too strict about filtering updates which are slightly less accurate than previous updates. The new behavior is to automatically use an update which comes from the same source as the previous used update.

Tested by driving around on local highways and observing that I get position updates around once per second or better.

To post a comment you must log in.
Revision history for this message
Jim Hodapp (jhodapp) wrote :

Looks good to me after discussing a few questions that I had about the code with Scott. I would prefer to not have the value.value syntax but Scott told me it's not possible to avoid that without breaking the provider API.

review: Approve (code)
Revision history for this message
Thomas Voß (thomas-voss) wrote :

LGTM.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'include/location_service/com/ubuntu/location/fusion_provider.h'
--- include/location_service/com/ubuntu/location/fusion_provider.h 2016-03-10 03:02:31 +0000
+++ include/location_service/com/ubuntu/location/fusion_provider.h 2016-06-08 22:07:21 +0000
@@ -48,7 +48,7 @@
48 void stop_velocity_updates() override;48 void stop_velocity_updates() override;
4949
50private:50private:
51 Optional<Update<Position>> last_position;51 Optional<WithSource<Update<Position>>> last_position;
52 std::set<Provider::Ptr> providers;52 std::set<Provider::Ptr> providers;
53 std::vector<core::ScopedConnection> connections;53 std::vector<core::ScopedConnection> connections;
54};54};
5555
=== modified file 'include/location_service/com/ubuntu/location/newer_or_more_accurate_update_selector.h'
--- include/location_service/com/ubuntu/location/newer_or_more_accurate_update_selector.h 2016-03-10 03:02:31 +0000
+++ include/location_service/com/ubuntu/location/newer_or_more_accurate_update_selector.h 2016-06-08 22:07:21 +0000
@@ -31,23 +31,28 @@
31public:31public:
32 typedef std::shared_ptr<NewerOrMoreAccurateUpdateSelector> Ptr;32 typedef std::shared_ptr<NewerOrMoreAccurateUpdateSelector> Ptr;
3333
34 Update<Position> select(const Update<Position>& older,34 WithSource<Update<Position>> select(const WithSource<Update<Position>>& older,
35 const Update<Position>& newer) override35 const WithSource<Update<Position>>& newer) override
36 {36 {
37 // Basically copied this value from the Android fusion provider37 // Basically copied this value from the Android fusion provider
38 static const std::chrono::seconds cutoff(11);38 static const std::chrono::seconds cutoff(11);
3939
40 // If the new position is from the same source as the old one then just use it
41 if (newer.source == older.source) {
42 return newer;
43 }
44
40 // If the new position is newer by a significant margin then just use it45 // If the new position is newer by a significant margin then just use it
41 if (newer.when > older.when + cutoff) {46 if (newer.value.when > older.value.when + cutoff) {
42 return newer;47 return newer;
43 }48 }
4449
45 // Choose the position with the smaller accuracy circle if both have them50 // Choose the position with the smaller accuracy circle if both have them
46 if (!older.value.accuracy.horizontal)51 if (!older.value.value.accuracy.horizontal)
47 return newer;52 return newer;
48 if (!newer.value.accuracy.horizontal)53 if (!newer.value.value.accuracy.horizontal)
49 return older;54 return older;
50 if (newer.value.accuracy.horizontal < older.value.accuracy.horizontal)55 if (newer.value.value.accuracy.horizontal < older.value.value.accuracy.horizontal)
51 return newer;56 return newer;
52 else57 else
53 return older;58 return older;
5459
=== modified file 'include/location_service/com/ubuntu/location/newer_update_selector.h'
--- include/location_service/com/ubuntu/location/newer_update_selector.h 2016-03-10 03:02:31 +0000
+++ include/location_service/com/ubuntu/location/newer_update_selector.h 2016-06-08 22:07:21 +0000
@@ -31,8 +31,8 @@
31public:31public:
32 typedef std::shared_ptr<NewerUpdateSelector> Ptr;32 typedef std::shared_ptr<NewerUpdateSelector> Ptr;
3333
34 Update<Position> select (const Update<Position>& older,34 virtual WithSource<Update<Position>> select(const WithSource<Update<Position>>& older,
35 const Update<Position>& newer) override35 const WithSource<Update<Position>>& newer) override
36 {36 {
37 return newer;37 return newer;
38 }38 }
3939
=== modified file 'include/location_service/com/ubuntu/location/update_selector.h'
--- include/location_service/com/ubuntu/location/update_selector.h 2016-03-10 03:02:31 +0000
+++ include/location_service/com/ubuntu/location/update_selector.h 2016-06-08 22:07:21 +0000
@@ -27,6 +27,10 @@
27{27{
28namespace location28namespace location
29{29{
30
31template<typename T>
32struct WithSource { std::shared_ptr<Provider> source; T value; };
33
30class UpdateSelector34class UpdateSelector
31{35{
32public:36public:
@@ -36,8 +40,8 @@
36 UpdateSelector& operator=(const UpdateSelector&) = delete;40 UpdateSelector& operator=(const UpdateSelector&) = delete;
37 virtual ~UpdateSelector() = default;41 virtual ~UpdateSelector() = default;
3842
39 virtual Update<Position> select(const Update<Position>& older,43 virtual WithSource<Update<Position>> select(const WithSource<Update<Position>>& older,
40 const Update<Position>& newer) = 0;44 const WithSource<Update<Position>>& newer) = 0;
4145
42protected:46protected:
43 UpdateSelector() = default;47 UpdateSelector() = default;
4448
=== modified file 'src/location_service/com/ubuntu/location/fusion_provider.cpp'
--- src/location_service/com/ubuntu/location/fusion_provider.cpp 2016-03-10 19:29:45 +0000
+++ src/location_service/com/ubuntu/location/fusion_provider.cpp 2016-06-08 22:07:21 +0000
@@ -37,7 +37,6 @@
37 cul::Provider::Requirements::satellites;37 cul::Provider::Requirements::satellites;
38}38}
3939
40
41cul::FusionProvider::FusionProvider(const std::set<location::Provider::Ptr>& providers, const UpdateSelector::Ptr& update_selector)40cul::FusionProvider::FusionProvider(const std::set<location::Provider::Ptr>& providers, const UpdateSelector::Ptr& update_selector)
42 : Provider{all_features(), all_requirements()},41 : Provider{all_features(), all_requirements()},
43 providers{providers}42 providers{providers}
@@ -46,14 +45,16 @@
46 for (auto provider : providers)45 for (auto provider : providers)
47 {46 {
48 connections.push_back(provider->updates().position.connect(47 connections.push_back(provider->updates().position.connect(
49 [this, update_selector](const cul::Update<cul::Position>& u)48 [this, provider, update_selector](const cul::Update<cul::Position>& u)
50 {49 {
51 // if this is the first update, use it50 // if this is the first update, use it
52 if (!last_position) {51 if (!last_position) {
53 mutable_updates().position(*(last_position = u));52 mutable_updates().position((*(last_position = WithSource<Update<Position>>{provider, u})).value);
53
54 // otherwise use the selector
54 } else {55 } else {
55 try {56 try {
56 mutable_updates().position(*(last_position = update_selector->select(*last_position, u)));57 mutable_updates().position((*(last_position = update_selector->select(*last_position, WithSource<Update<Position>>{provider, u}))).value);
57 } catch (const std::exception& e) {58 } catch (const std::exception& e) {
58 LOG(WARNING) << "Error while updating position";59 LOG(WARNING) << "Error while updating position";
59 }60 }
6061
=== modified file 'tests/provider_test.cpp'
--- tests/provider_test.cpp 2016-03-08 22:20:10 +0000
+++ tests/provider_test.cpp 2016-06-08 22:07:21 +0000
@@ -409,3 +409,33 @@
409 mp2.inject_update(after);409 mp2.inject_update(after);
410410
411}411}
412
413TEST(FusionProvider, update_from_same_provider_is_chosen)
414{
415 using namespace ::testing;
416
417 NiceMock<MockProvider> mp1;
418
419 cul::Provider::Ptr p1{std::addressof(mp1), [](cul::Provider*){}};
420
421 std::set<cul::Provider::Ptr> providers{p1};
422
423 cul::FusionProvider fp{providers, std::make_shared<cul::NewerOrMoreAccurateUpdateSelector>()};
424
425 cul::Update<cul::Position> before, after;
426 before.when = cul::Clock::now() - std::chrono::seconds(5);
427 before.value = cul::Position(cul::wgs84::Latitude(), cul::wgs84::Longitude(), cul::wgs84::Altitude(), cul::Position::Accuracy::Horizontal{50*cul::units::Meters});
428 after.when = cul::Clock::now();
429 after.value = cul::Position(cul::wgs84::Latitude(), cul::wgs84::Longitude(), cul::wgs84::Altitude(), cul::Position::Accuracy::Horizontal{500*cul::units::Meters});
430
431 NiceMock<MockEventConsumer> mec;
432 // We should see the "newer" position even though it's less accurate since
433 // it came from the same source
434 EXPECT_CALL(mec, on_new_position(before)).Times(1);
435 EXPECT_CALL(mec, on_new_position(after)).Times(1);
436
437 fp.updates().position.connect([&mec](const cul::Update<cul::Position>& p){mec.on_new_position(p);});
438
439 mp1.inject_update(before);
440 mp1.inject_update(after);
441}

Subscribers

People subscribed via source and target branches