Add primitive filter for AoA data 38/265338/2
authorjiung-yu <jiung.yu@samsung.com>
Fri, 15 Oct 2021 15:21:16 +0000 (00:21 +0900)
committerjiung-yu <jiung.yu@samsung.com>
Fri, 15 Oct 2021 15:23:12 +0000 (00:23 +0900)
Description : This commit is first filter to gather
field data to compensate elements of filters.
We will tunning this filter continuously with actual
test environment.

Change-Id: I05b092a31b5aaa9e864243c0755ac8243c79a6c2
Signed-off-by: Yu jiung <jiung.yu@samsung.com>
include/Node.h
packaging/uwb-manager.spec
src/CMakeLists.txt
src/LocationManager.cpp
src/UwbPosition.cpp
src/filters/GHFilter.h [new file with mode: 0644]

index 9dc65e616b5c93ba078b6e41a092b957d2554b3f..ad3bf264137c8040c29763ce62abd8fe409c3878 100755 (executable)
@@ -19,6 +19,7 @@
 
 #include <chrono>
 
+#include <GHFilter.h>
 #include <uwb-def.h>
 
 #define TECH_UNKNOWN 0x00
@@ -36,21 +37,29 @@ public:
 
        Node(int pan_id, unsigned long long node_id, int x, int y, int z, int range, int aoa, int pdoa) :
                _distance(0), _pan_id(pan_id), _node_id(node_id), _x(x), _y(y), _z(z),
-               _range(range), _aoa(aoa), _pdoa(pdoa),
+               _range(range), _filtered_range(), _aoa(aoa), _filtered_aoa(), _pdoa(pdoa),
                _is_remote(false), _is_calculated(false), _tech(TECH_UNKNOWN),
-               _last_update(std::chrono::steady_clock::now()) {};
+               _last_update(std::chrono::steady_clock::now()) {
+                       _filtered_range.setState(range);
+                       _filtered_aoa.setState(aoa);
+               };
 
        Node(uwb_node_s *node) :
                _distance(node->distance), _pan_id(node->pan_id), _node_id(node->node_id),
-               _x(node->x), _y(node->y), _z(node->z), _range(node->range), _aoa(node->aoa), _pdoa(node->pdoa),
+               _x(node->x), _y(node->y), _z(node->z), _range(node->range), _filtered_range(),
+               _aoa(node->aoa), _filtered_aoa(), _pdoa(node->pdoa),
                _is_remote(node->is_remote), _is_calculated(false), _tech(TECH_UWB),
-               _last_update(std::chrono::steady_clock::now()){};
+               _last_update(std::chrono::steady_clock::now()) {
+                       _filtered_range.setState(node->range);
+                       _filtered_aoa.setState(node->aoa);
+               };
 
        Node(Node *node) :
                _distance(node->_distance), _pan_id(node->_pan_id), _node_id(node->_node_id),
-               _x(node->_x), _y(node->_y), _z(node->_z), _range(node->_range), _aoa(node->_aoa), _pdoa(node->_pdoa),
+               _x(node->_x), _y(node->_y), _z(node->_z), _range(node->_range), _filtered_range(node->_filtered_range),
+               _aoa(node->_aoa), _filtered_aoa(node->_filtered_aoa), _pdoa(node->_pdoa),
                _is_remote(node->_is_remote), _is_calculated(node->_is_calculated), _tech(node->_tech),
-               _last_update(node->_last_update){};
+               _last_update(node->_last_update) {};
 
        //~Node(){UWB_LOGI("%llu removed", _node_id);}
        Node(const Node &node) = default;
@@ -71,8 +80,10 @@ public:
        int getZ(void) {return _z;};
        void setZ(int z) {_z = z;};
        int getRange(void) {return _range;};
+       float getFilteredRange(void) { return _filtered_range.getState(); };
        void setRange(int range) {_range = range;};
        int getAoa(void) {return _aoa;};
+       float getFilteredAoa(void) { return _filtered_aoa.getState(); };
        void setAoa(int aoa) {_aoa = aoa;};
        int getPdoa(void) {return _pdoa;};
        void setPdoa(int pdoa) {_pdoa = pdoa;};
@@ -85,6 +96,13 @@ public:
        std::chrono::steady_clock::time_point getLastUpdate(void) {return _last_update;};
        void setLastUpdate(std::chrono::steady_clock::time_point update_time) {_last_update = update_time;};
        bool hasSamePosition(Node *node) {return (_x == node->_x && _y == node->_y && _z == node->_z);};
+       void updateFilters(void) {
+               _filtered_range.predict();
+               _filtered_aoa.predict();
+
+               _filtered_range.update(_range);
+               _filtered_aoa.update(_aoa);
+       }
 private:
        unsigned long long _distance;
        int _pan_id;
@@ -93,7 +111,9 @@ private:
        int _y;
        int _z;
        int _range;
+       GHFilter _filtered_range;
        int _aoa;
+       GHFilter _filtered_aoa;
        int _pdoa;
        bool _is_remote;
        bool _is_calculated;
index 588cda0082b5ac9c4533ded996a45a970253585f..2721e405bbdc0a4bec600849f5f416df68ffa635 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       uwb-manager
 Summary:    This is the daemon managing UWB related functionalities
-Version:    0.0.5
+Version:    0.0.6
 Release:    1
 Group:      Network & Connectivity/Wireless
 License:    Apache-2.0
index 377bb7abacaa3a209d196a3b0f49910b38993efa..37ae4ca1b690ccb0bddf2ce5516c81e630b7101c 100755 (executable)
@@ -33,6 +33,7 @@ LINK_DIRECTORIES(${TARGET_UWB_MANAGER_REQ_PKGS_LIBRARY_DIRS})
 INCLUDE_DIRECTORIES(
        ${CMAKE_SOURCE_DIR}/include
        ${CMAKE_SOURCE_DIR}/interface
+       ${CMAKE_SOURCE_DIR}/src/filters
        )
 
 FILE(GLOB SRCS *.cpp)
index 89bfcf4f39c50335e77d4bbf4b165ce5dd856954..3c1adb3a03ee495b304e475eafcee28d7b1a3b56 100644 (file)
@@ -327,17 +327,21 @@ int LocationManager::connectMqttBroker(const char *server, int port)
 
 Node &LocationManager::getCurrentPosition(void)
 {
+       __UWB_LOG_FUNC_ENTER__;
        if (!this->_mqtt_context->isConnected())
                this->updateUwbPosition();
 
+       __UWB_LOG_FUNC_EXIT__;
        return _current;
 }
 
 std::map<int, std::unique_ptr<Node>> &LocationManager::getNodeMap(void)
 {
+       __UWB_LOG_FUNC_ENTER__;
        if (!this->_mqtt_context->isConnected())
                this->updateUwbPosition();
 
+       __UWB_LOG_FUNC_EXIT__;
        return _node_map;
 }
 
@@ -355,21 +359,22 @@ void LocationManager::updateUwbNodes(void)
        for (; it != uwb_node_list->end(); ++it) {
                Node *p_node = (*it).get();
 
-       auto itr = this->_node_map.find(p_node->getNodeId());
-       bool added = itr == this->_node_map.end();
-
-       p_node->setLastUpdate(std::chrono::steady_clock::now());
-       this->_node_map[p_node->getNodeId()] =
-                       std::unique_ptr<Node>((Node *)new Node{p_node});
-
-       if (added) {
-               if (this->_node_added_cb)
-                       this->_node_added_cb(p_node);
-       } else {
-               if (this->_node_updated_cb)
-                       this->_node_updated_cb(p_node);
+               auto itr = this->_node_map.find(p_node->getNodeId());
+               bool added = itr == this->_node_map.end();
+
+               p_node->setLastUpdate(std::chrono::steady_clock::now());
+               p_node->updateFilters();
+               this->_node_map[p_node->getNodeId()] =
+               std::unique_ptr<Node>((Node *)new Node{p_node});
+
+               if (added) {
+                       if (this->_node_added_cb)
+                               this->_node_added_cb(p_node);
+               } else {
+                       if (this->_node_updated_cb)
+                               this->_node_updated_cb(p_node);
+               }
        }
-    }
 }
 
 void LocationManager::removeOutdatedUwbNodes(void)
@@ -381,12 +386,12 @@ void LocationManager::removeOutdatedUwbNodes(void)
        */
 
        for (auto itr = this->_node_map.begin(); itr != this->_node_map.end();) {
-       Node *node_ptr = itr->second.get();
-       if (std::chrono::duration_cast<std::chrono::milliseconds>(current_mil - node_ptr->getLastUpdate()).count()
-                       > LocationManager::_default_remove_duration.count()) {
-               if (this->_node_removed_cb)
-                       this->_node_removed_cb(node_ptr);
-               itr = this->_node_map.erase(itr);
+               Node *node_ptr = itr->second.get();
+               if (std::chrono::duration_cast<std::chrono::milliseconds>(current_mil - node_ptr->getLastUpdate()).count()
+                               > LocationManager::_default_remove_duration.count()) {
+                       if (this->_node_removed_cb)
+                               this->_node_removed_cb(node_ptr);
+                       itr = this->_node_map.erase(itr);
        } else
                ++itr;
        }
index 8656ac09e53e9dec71b70c3731fc44bb0c5b602c..554746b1697b8f3a2a109a4aca71b51c248ebb20 100755 (executable)
@@ -25,17 +25,23 @@ using namespace UwbManagerNamespace;
 
 int UwbPosition::updateUwbOwnNode()
 {
-       if (this->_uwb_hal == nullptr)
+       __UWB_LOG_FUNC_ENTER__;
+       if (this->_uwb_hal == nullptr) {
+               __UWB_LOG_FUNC_EXIT__;
                return 0;
+       }
 
        uwb_node_s *own_node;
        int res = this->_uwb_hal->getOwnNode(&own_node);
-       if (res != 0 || !own_node)
+       if (res != 0 || !own_node) {
+               __UWB_LOG_FUNC_EXIT__;
                return -1;
+       }
 
        this->setOwnNode(Node{own_node});
        free(own_node);
 
+       __UWB_LOG_FUNC_EXIT__;
        return 0;
 }
 
diff --git a/src/filters/GHFilter.h b/src/filters/GHFilter.h
new file mode 100644 (file)
index 0000000..7fc166f
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __GH_FILTER_H__
+#define __GH_FILTER_H__
+
+class GHFilter {
+public:
+
+       void reset(void) {
+               _state  = 0;
+               _P = 0;
+       }
+
+       void setState(float state) {
+               _state = state;
+               return;
+       };
+
+       void setProcessVariance(float P) {
+               _P = P;
+               return;
+       };
+
+       //By system Modeling, P means rate but it expressed as matrix due to
+       //abstract interface
+       void predict(void) {
+               // System Modeling: X(n) = X(n - 1) + P * dt
+               _state = _state + _P * _time_delta;
+
+               //According to System modeling, there's no rate change in prediction
+       };
+
+       void update(float measurement) {
+
+               float residual = measurement - _state;
+
+               //h is the scaling for the change in measurement over time
+               _P = _P + _h * residual / _time_delta;
+
+               //g is the scaling we used for the measurement
+               _state = _state + _g * residual;
+               return;
+       };
+
+       float getState(void) { return _state; };
+private:
+       float _state;
+       float _P;
+
+    //Temporal value for g, h from https://en.wikipedia.org/wiki/Alpha_beta_filter
+       static constexpr float _g  = 0.85;
+       static constexpr float _h = 0.005;
+       static constexpr float _time_delta = 1.0;
+};
+
+#endif /* __GH_FILTER_H__ */