#include /* tests for AP_NavEKF/EKF_Buffer.cpp */ #include #include #include const AP_HAL::HAL& hal = AP_HAL::get_HAL(); #if CONFIG_HAL_BOARD == HAL_BOARD_SITL || CONFIG_HAL_BOARD == HAL_BOARD_LINUX TEST(EKF_Buffer, EKF_Buffer) { struct test_data : EKF_obs_element_t { uint32_t data; }; EKF_obs_buffer_t buf; buf.init(8); struct test_data d, d2; uint32_t now = 100; d.data = 17; d.time_ms = now++; buf.push(d); EXPECT_TRUE(buf.recall(d2, now)); EXPECT_EQ(d2.data, d.data); EXPECT_EQ(d2.time_ms, uint32_t(100)); d.time_ms = 101; buf.push(d); d.time_ms = 102; buf.push(d); // recall first element EXPECT_TRUE(buf.recall(d2, 101)); EXPECT_EQ(d2.data, d.data); EXPECT_EQ(d2.time_ms, uint32_t(101)); EXPECT_TRUE(buf.recall(d2, 102)); EXPECT_EQ(d2.data, d.data); EXPECT_EQ(d2.time_ms, uint32_t(102)); EXPECT_FALSE(buf.recall(d2, 103)); d.time_ms = 101; buf.push(d); d.time_ms = 102; buf.push(d); // recall 2nd element, note that first element is discarded EXPECT_TRUE(buf.recall(d2, 103)); EXPECT_EQ(d2.data, d.data); EXPECT_EQ(d2.time_ms, uint32_t(102)); EXPECT_FALSE(buf.recall(d2, 103)); EXPECT_FALSE(buf.recall(d2, 103)); // test overflow of buffer for (uint8_t i=0; i<16; i++) { d.time_ms = 100+i; d.data = 1000+i; buf.push(d); } for (uint8_t i=0; i<16; i++) { if (i < 8) { EXPECT_TRUE(buf.recall(d2, 108+i)); } else { EXPECT_FALSE(buf.recall(d2, 1100)); } } // test with an element that is too old d.time_ms = 101; d.data = 200; buf.push(d); d.time_ms = 1002; d.data = 2000; buf.push(d); // recall element, first one is too old so will be discarded EXPECT_TRUE(buf.recall(d2, 1003)); EXPECT_EQ(d2.data, 2000U); EXPECT_EQ(d2.time_ms, uint32_t(1002)); EXPECT_FALSE(buf.recall(d2, 103)); // test 32 bit time wrap d.time_ms = 0xFFFFFFF0U; d.data = 200; buf.push(d); d.time_ms = 0xFFFFFFFAU; d.data = 2000; buf.push(d); d.time_ms = 0xFFFFFFFBU; d.data = 2001; buf.push(d); // recall element, first one is too old so will be discarded EXPECT_TRUE(buf.recall(d2, 10)); EXPECT_EQ(d2.data, 2001U); EXPECT_EQ(d2.time_ms, uint32_t(0xFFFFFFFBU)); EXPECT_FALSE(buf.recall(d2, 103)); // test 32 bit time wrap with a too old element d.time_ms = 0xFFFFFFFFU - 1000U; d.data = 200; buf.push(d); d.time_ms = 0xFFFFFFFBU; d.data = 2001; buf.push(d); // recall element, first one is too old so will be discarded EXPECT_TRUE(buf.recall(d2, 10)); EXPECT_EQ(d2.data, 2001U); EXPECT_EQ(d2.time_ms, uint32_t(0xFFFFFFFBU)); EXPECT_FALSE(buf.recall(d2, 103)); } TEST(ekf_imu_buffer, one_element_case) { // test degenerate 1-element case: struct element { uint8_t value; }; ekf_imu_buffer *b = NEW_NOTHROW ekf_imu_buffer(sizeof(element)); b->init(1); // 1 element EXPECT_EQ(b->is_filled(), false); EXPECT_EQ(b->get_oldest_index(), b->get_youngest_index()); const element e { 34 }; b->push_youngest_element((void*)&e); EXPECT_EQ(b->is_filled(), true); EXPECT_EQ(b->get_oldest_index(), b->get_youngest_index()); element returned_element {}; b->get_oldest_element((void*)&returned_element); EXPECT_EQ(e.value, returned_element.value); element *another_returned_element = (element*)b->get(0); EXPECT_EQ(e.value, another_returned_element->value); // we don't do bounds checking, so get here returns non-nullptr: // another_returned_element = (element*)b.get(17); // EXPECT_EQ(another_returned_element, nullptr); b->reset(); EXPECT_EQ(b->get_oldest_index(), b->get_youngest_index()); // we don't do bounds checking, so get here returns non-nullptr: // another_returned_element = (element*)b.get(0); // EXPECT_EQ(another_returned_element, nullptr); } TEST(ekf_imu_buffer, is_filled) { // https://github.com/ArduPilot/ardupilot/issues/25316 struct element { uint8_t value; }; ekf_imu_buffer *b = NEW_NOTHROW ekf_imu_buffer(sizeof(element)); b->init(4); // 4 elements const element e { 34 }; EXPECT_EQ(b->is_filled(), false); b->push_youngest_element((void*)&e); EXPECT_EQ(b->is_filled(), false); b->push_youngest_element((void*)&e); EXPECT_EQ(b->is_filled(), false); b->push_youngest_element((void*)&e); EXPECT_EQ(b->is_filled(), false); b->push_youngest_element((void*)&e); EXPECT_EQ(b->is_filled(), true); } AP_GTEST_MAIN() #endif // HAL_SITL or HAL_LINUX