Skip to content

Commit 6d3a34a

Browse files
committed
system_tests: adapt test for raw bytes API
We probably shouldn't rely on heartbeats as these are sent anyway.
1 parent 0bb58fa commit 6d3a34a

File tree

1 file changed

+77
-60
lines changed

1 file changed

+77
-60
lines changed

src/system_tests/raw_bytes.cpp

Lines changed: 77 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "log.h"
22
#include "mavsdk.h"
3+
#include "plugins/telemetry_server/telemetry_server.h"
34
#include "mavlink_include.h"
45
#include <atomic>
56
#include <chrono>
@@ -9,39 +10,36 @@
910

1011
using namespace mavsdk;
1112

12-
TEST(SystemTest, RawBytesHeartbeat)
13+
TEST(SystemTest, RawBytesSendReceive)
1314
{
14-
// Create a MAVSDK instance that will receive and respond to raw bytes
15-
Mavsdk mavsdk_responder{Mavsdk::Configuration{ComponentType::Autopilot}};
15+
// Test 1: Verify subscribe_raw_bytes_to_be_sent captures outgoing messages
16+
Mavsdk mavsdk_autopilot{Mavsdk::Configuration{ComponentType::Autopilot}};
17+
ASSERT_EQ(mavsdk_autopilot.add_any_connection("raw://"), ConnectionResult::Success);
1618

17-
// Add a raw connection - this will automatically enable heartbeats
18-
ASSERT_EQ(mavsdk_responder.add_any_connection("raw://"), ConnectionResult::Success);
19+
auto telemetry_server = std::make_shared<TelemetryServer>(mavsdk_autopilot.server_component());
1920

20-
// Set up a promise/future to capture the heartbeat response
21+
// Set up to capture outgoing raw bytes
2122
auto prom = std::promise<void>();
2223
auto fut = prom.get_future();
23-
bool heartbeat_received = false;
24+
std::atomic<bool> message_captured{false};
2425

25-
// Subscribe to raw bytes to capture the heartbeat response
26-
auto handle = mavsdk_responder.subscribe_raw_bytes_to_be_sent(
27-
[&prom, &heartbeat_received](const char* bytes, size_t length) {
28-
LogInfo() << "Received " << length << " raw bytes";
29-
30-
// Parse to check if this is a heartbeat
26+
// Subscribe to outgoing raw bytes
27+
auto handle = mavsdk_autopilot.subscribe_raw_bytes_to_be_sent(
28+
[&prom, &message_captured](const char* bytes, size_t length) {
29+
// Parse the bytes
3130
mavlink_message_t msg = {};
3231
mavlink_status_t status = {};
3332

3433
for (size_t i = 0; i < length; ++i) {
3534
if (mavlink_parse_char(
3635
MAVLINK_COMM_0, static_cast<uint8_t>(bytes[i]), &msg, &status)) {
37-
if (msg.msgid == MAVLINK_MSG_ID_HEARTBEAT) {
38-
LogInfo() << "Captured HEARTBEAT message from system " << (int)msg.sysid
39-
<< ", component " << (int)msg.compid;
40-
if (!heartbeat_received) {
41-
heartbeat_received = true;
42-
prom.set_value();
43-
}
44-
return;
36+
LogInfo() << "Captured outgoing message ID " << msg.msgid;
37+
38+
// Look for GLOBAL_POSITION_INT message
39+
if (msg.msgid == MAVLINK_MSG_ID_GLOBAL_POSITION_INT &&
40+
!message_captured.exchange(true)) {
41+
LogInfo() << "Captured GLOBAL_POSITION_INT being sent";
42+
prom.set_value();
4543
}
4644
}
4745
}
@@ -50,43 +48,62 @@ TEST(SystemTest, RawBytesHeartbeat)
5048
// Give subscription time to be registered
5149
std::this_thread::sleep_for(std::chrono::milliseconds(100));
5250

53-
// Create a raw heartbeat message
54-
mavlink_message_t heartbeat_msg;
55-
mavlink_heartbeat_t heartbeat;
56-
heartbeat.type = MAV_TYPE_GCS;
57-
heartbeat.autopilot = MAV_AUTOPILOT_INVALID;
58-
heartbeat.base_mode = 0;
59-
heartbeat.custom_mode = 0;
60-
heartbeat.system_status = MAV_STATE_ACTIVE;
61-
heartbeat.mavlink_version = 3;
62-
63-
mavlink_msg_heartbeat_encode(245, 190, &heartbeat_msg, &heartbeat);
64-
65-
// Serialize the heartbeat to raw bytes
66-
std::vector<uint8_t> heartbeat_bytes(MAVLINK_MAX_PACKET_LEN);
67-
uint16_t len = mavlink_msg_to_send_buffer(heartbeat_bytes.data(), &heartbeat_msg);
68-
heartbeat_bytes.resize(len);
69-
70-
// Send periodic heartbeats at 1 Hz to keep the system alive
71-
std::atomic<bool> should_send_heartbeats{true};
72-
std::thread heartbeat_thread([&]() {
73-
while (should_send_heartbeats) {
74-
LogInfo() << "Sending raw heartbeat (" << len << " bytes)...";
75-
mavsdk_responder.pass_received_raw_bytes(
76-
reinterpret_cast<const char*>(heartbeat_bytes.data()), len);
77-
std::this_thread::sleep_for(std::chrono::seconds(1));
78-
}
79-
});
80-
81-
// Wait for heartbeat response (responder should send heartbeats automatically)
82-
// The subscription callback should be triggered when heartbeats are sent out
83-
auto status = fut.wait_for(std::chrono::seconds(5));
84-
ASSERT_EQ(status, std::future_status::ready)
85-
<< "Did not receive heartbeat response within timeout";
86-
87-
// Stop sending heartbeats and clean up
88-
should_send_heartbeats = false;
89-
heartbeat_thread.join();
90-
91-
mavsdk_responder.unsubscribe_raw_bytes_to_be_sent(handle);
51+
// Publish a position which should trigger outgoing message
52+
TelemetryServer::Position position{};
53+
position.latitude_deg = 47.3977;
54+
position.longitude_deg = 8.5456;
55+
position.absolute_altitude_m = 488.0f;
56+
position.relative_altitude_m = 10.0f;
57+
58+
TelemetryServer::VelocityNed velocity{};
59+
velocity.north_m_s = 0.0f;
60+
velocity.east_m_s = 0.0f;
61+
velocity.down_m_s = 0.0f;
62+
63+
TelemetryServer::Heading heading{};
64+
heading.heading_deg = 90.0f;
65+
66+
LogInfo() << "Publishing position via TelemetryServer...";
67+
telemetry_server->publish_position(position, velocity, heading);
68+
69+
// Wait for the message to be captured
70+
auto result = fut.wait_for(std::chrono::seconds(2));
71+
ASSERT_EQ(result, std::future_status::ready)
72+
<< "Did not capture GLOBAL_POSITION_INT through raw bytes subscription";
73+
74+
mavsdk_autopilot.unsubscribe_raw_bytes_to_be_sent(handle);
75+
76+
// Test 2: Verify pass_received_raw_bytes processes incoming messages
77+
Mavsdk mavsdk_gcs{Mavsdk::Configuration{ComponentType::GroundStation}};
78+
ASSERT_EQ(mavsdk_gcs.add_any_connection("raw://"), ConnectionResult::Success);
79+
80+
// Create a PING message
81+
mavlink_message_t ping_msg;
82+
mavlink_ping_t ping;
83+
ping.time_usec = 123456;
84+
ping.seq = 42;
85+
ping.target_system = 0; // Broadcast
86+
ping.target_component = 0;
87+
88+
mavlink_msg_ping_encode(1, 1, &ping_msg, &ping);
89+
90+
// Serialize to bytes
91+
std::vector<uint8_t> ping_bytes(MAVLINK_MAX_PACKET_LEN);
92+
uint16_t len = mavlink_msg_to_send_buffer(ping_bytes.data(), &ping_msg);
93+
ping_bytes.resize(len);
94+
95+
LogInfo() << "Passing " << len << " raw bytes (PING) into MAVSDK...";
96+
97+
// This should be processed and create a system
98+
mavsdk_gcs.pass_received_raw_bytes(reinterpret_cast<const char*>(ping_bytes.data()), len);
99+
100+
// Give it time to process
101+
std::this_thread::sleep_for(std::chrono::milliseconds(200));
102+
103+
// Verify a system was created from the ping
104+
auto systems = mavsdk_gcs.systems();
105+
ASSERT_FALSE(systems.empty()) << "No system was created from received raw bytes";
106+
ASSERT_EQ(systems[0]->get_system_id(), 1) << "System ID mismatch";
107+
LogInfo() << "Successfully created system from raw bytes with ID "
108+
<< systems[0]->get_system_id();
92109
}

0 commit comments

Comments
 (0)