INSTINCT Code Coverage Report


Directory: src/
File: Nodes/DataProvider/IMU/Sensors/KvhSensor.cpp
Date: 2025-11-25 23:34:18
Exec Total Coverage
Lines: 14 74 18.9%
Functions: 4 12 33.3%
Branches: 10 94 10.6%

Line Branch Exec Source
1 // This file is part of INSTINCT, the INS Toolkit for Integrated
2 // Navigation Concepts and Training by the Institute of Navigation of
3 // the University of Stuttgart, Germany.
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9 #include "KvhSensor.hpp"
10
11 #include "util/Logger.hpp"
12
13 #include "internal/gui/widgets/HelpMarker.hpp"
14
15 #include "internal/FlowManager.hpp"
16
17 #include "util/Time/TimeBase.hpp"
18 #include "util/Vendor/KVH/KvhUtilities.hpp"
19
20 #include "NodeData/IMU/KvhObs.hpp"
21
22 114 NAV::KvhSensor::KvhSensor()
23
3/6
✓ Branch 1 taken 114 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 114 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 114 times.
✗ Branch 10 not taken.
114 : Imu(typeStatic())
24 {
25 LOG_TRACE("{}: called", name);
26
27 114 _onlyRealTime = true;
28 114 _hasConfig = true;
29 114 _guiConfigDefaultWindowSize = { 360, 70 };
30
31 // TODO: Update the library to handle different baudrates
32
1/2
✓ Branch 1 taken 114 times.
✗ Branch 2 not taken.
114 _selectedBaudrate = baudrate2Selection(Baudrate::BAUDRATE_921600);
33
34
4/8
✓ Branch 2 taken 114 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 114 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 114 times.
✓ Branch 10 taken 114 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
456 CreateOutputPin("KvhObs", Pin::Type::Flow, { NAV::KvhObs::type() });
35 228 }
36
37 228 NAV::KvhSensor::~KvhSensor()
38 {
39 LOG_TRACE("{}: called", nameId());
40 228 }
41
42 228 std::string NAV::KvhSensor::typeStatic()
43 {
44
1/2
✓ Branch 1 taken 228 times.
✗ Branch 2 not taken.
456 return "KvhSensor";
45 }
46
47 ✗ std::string NAV::KvhSensor::type() const
48 {
49 ✗ return typeStatic();
50 }
51
52 114 std::string NAV::KvhSensor::category()
53 {
54
1/2
✓ Branch 1 taken 114 times.
✗ Branch 2 not taken.
228 return "Data Provider";
55 }
56
57 ✗ void NAV::KvhSensor::guiConfig()
58 {
59 ✗ if (ImGui::InputTextWithHint("SensorPort", "/dev/ttyUSB0", &_sensorPort))
60 {
61 ✗ LOG_DEBUG("{}: SensorPort changed to {}", nameId(), _sensorPort);
62 ✗ flow::ApplyChanges();
63 ✗ doDeinitialize();
64 }
65 ✗ ImGui::SameLine();
66 ✗ gui::widgets::HelpMarker("COM port where the sensor is attached to\n"
67 "- \"COM1\" (Windows format for physical and virtual (USB) serial port)\n"
68 "- \"/dev/ttyS1\" (Linux format for physical serial port)\n"
69 "- \"/dev/ttyUSB0\" (Linux format for virtual (USB) serial port)\n"
70 "- \"/dev/tty.usbserial-FTXXXXXX\" (Mac OS X format for virtual (USB) serial port)\n"
71 "- \"/dev/ttyS0\" (CYGWIN format. Usually the Windows COM port number minus 1. This would connect to COM1)");
72
73 ✗ Imu::guiConfig();
74 ✗ }
75
76 ✗ [[nodiscard]] json NAV::KvhSensor::save() const
77 {
78 LOG_TRACE("{}: called", nameId());
79
80 ✗ json j;
81
82 ✗ j["UartSensor"] = UartSensor::save();
83 ✗ j["Imu"] = Imu::save();
84
85 ✗ return j;
86 ✗ }
87
88 ✗ void NAV::KvhSensor::restore(json const& j)
89 {
90 LOG_TRACE("{}: called", nameId());
91
92 ✗ if (j.contains("UartSensor"))
93 {
94 ✗ UartSensor::restore(j.at("UartSensor"));
95 }
96 ✗ if (j.contains("Imu"))
97 {
98 ✗ Imu::restore(j.at("Imu"));
99 }
100 ✗ }
101
102 ✗ bool NAV::KvhSensor::resetNode()
103 {
104 ✗ return true;
105 }
106
107 ✗ bool NAV::KvhSensor::initialize()
108 {
109 LOG_TRACE("{}: called", nameId());
110
111 // connect to the sensor
112 try
113 {
114 ✗ _sensor->connect(_sensorPort, sensorBaudrate());
115
116 ✗ LOG_DEBUG("{} connected on port {} with baudrate {}", nameId(), _sensorPort, sensorBaudrate());
117 }
118 ✗ catch (...)
119 {
120 ✗ LOG_ERROR("{} could not connect", nameId());
121 ✗ return false;
122 ✗ }
123
124 ✗ _sensor->registerAsyncPacketReceivedHandler(this, asciiOrBinaryAsyncMessageReceived);
125
126 ✗ return true;
127 }
128
129 ✗ void NAV::KvhSensor::deinitialize()
130 {
131 LOG_TRACE("{}: called", nameId());
132
133 ✗ if (!isInitialized())
134 {
135 ✗ return;
136 }
137
138 ✗ if (_sensor->isConnected())
139 {
140 try
141 {
142 ✗ _sensor->unregisterAsyncPacketReceivedHandler();
143 }
144 ✗ catch (...) // NOLINT(bugprone-empty-catch)
145 ✗ {}
146 ✗ _sensor->disconnect();
147 }
148 }
149
150 ✗ void NAV::KvhSensor::asciiOrBinaryAsyncMessageReceived(void* userData, uart::protocol::Packet& p, [[maybe_unused]] size_t index)
151 {
152 ✗ auto* kvhSensor = static_cast<KvhSensor*>(userData);
153
154 ✗ if (p.type() == uart::protocol::Packet::Type::TYPE_BINARY)
155 {
156 ✗ auto obs = std::make_shared<KvhObs>(kvhSensor->_imuPos, p);
157
158 ✗ vendor::kvh::decryptKvhObs(obs);
159
160 LOG_DATA("DATA({}): {}, {}, {}",
161 kvhSensor->name, obs->sequenceNumber, obs->temperature.value(), fmt::streamed(obs->status));
162
163 // Check if a packet was skipped
164 ✗ if (kvhSensor->_prevSequenceNumber == UINT8_MAX)
165 {
166 ✗ kvhSensor->_prevSequenceNumber = obs->sequenceNumber;
167 }
168 ✗ if (obs->sequenceNumber != 0 && (obs->sequenceNumber < kvhSensor->_prevSequenceNumber || obs->sequenceNumber > kvhSensor->_prevSequenceNumber + 2))
169 {
170 ✗ LOG_WARN("{}: Sequence Number changed from {} to {}", kvhSensor->name, kvhSensor->_prevSequenceNumber, obs->sequenceNumber);
171 }
172 ✗ kvhSensor->_prevSequenceNumber = obs->sequenceNumber;
173
174 // Calls all the callbacks
175 ✗ if (InsTime currentTime = util::time::GetCurrentInsTime();
176 ✗ !currentTime.empty())
177 {
178 ✗ obs->insTime = currentTime;
179 }
180 ✗ kvhSensor->invokeCallbacks(OUTPUT_PORT_INDEX_KVH_OBS, obs);
181 ✗ }
182 ✗ else if (p.type() == uart::protocol::Packet::Type::TYPE_ASCII)
183 {
184 ✗ LOG_WARN("{}: Received an ASCII Async message: {}", kvhSensor->name, p.datastr());
185 }
186 ✗ }
187