/* * This file is part of Cleanflight. * * Cleanflight is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Cleanflight is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Cleanflight. If not, see . */ #include extern "C" { #include "build_config.h" #include "drivers/sonar_hcsr04.h" #include "sensors/sonar.h" extern int32_t measurement; extern int16_t sonarMaxTiltDeciDegrees; void sonarInit(const sonarHardware_t *sonarHardware); } #include "unittest_macros.h" #include "gtest/gtest.h" TEST(SonarUnittest, TestConstants) { sonarInit(0); // SONAR_OUT_OF_RANGE must be negative EXPECT_LE(SONAR_OUT_OF_RANGE, 0); // Check against gross errors in max range constants EXPECT_GT(HCSR04_MAX_RANGE_CM, 100); } TEST(SonarUnittest, TestSonarInit) { sonarInit(0); EXPECT_EQ(sonarMaxRangeCm, HCSR04_MAX_RANGE_CM); // Check against gross errors in max range values EXPECT_GE(sonarMaxAltWithTiltCm, 100); EXPECT_LE(sonarMaxAltWithTiltCm, sonarMaxRangeCm); EXPECT_GE(sonarCfAltCm, 100); EXPECT_LE(sonarCfAltCm, sonarMaxRangeCm); EXPECT_LE(sonarCfAltCm, sonarMaxAltWithTiltCm); // Check reasonable values for maximum tilt EXPECT_GE(sonarMaxTiltDeciDegrees, 0); EXPECT_LE(sonarMaxTiltDeciDegrees, 450); } TEST(SonarUnittest, TestDistance) { // Check sonar pulse time converted correctly to cm const int echoMicroSecondsPerCm = 59; measurement = 0; EXPECT_EQ(hcsr04_get_distance(), 0); measurement = echoMicroSecondsPerCm; EXPECT_EQ(hcsr04_get_distance(), 1); measurement = 10 * echoMicroSecondsPerCm; EXPECT_EQ(hcsr04_get_distance(), 10); measurement = HCSR04_MAX_RANGE_CM * echoMicroSecondsPerCm; EXPECT_EQ(hcsr04_get_distance(), HCSR04_MAX_RANGE_CM); } TEST(SonarUnittest, TestAltitude) { sonarInit(0); // Check distance not modified if no tilt EXPECT_EQ(sonarCalculateAltitude(0, 0, 0), 0); EXPECT_EQ(sonarGetLatestAltitude(), 0); EXPECT_EQ(sonarCalculateAltitude(100, 0, 0), 100); EXPECT_EQ(sonarGetLatestAltitude(), 100); // Check that out of range is returned if tilt is too large EXPECT_EQ(sonarCalculateAltitude(0, sonarMaxTiltDeciDegrees+1, 0), SONAR_OUT_OF_RANGE); EXPECT_EQ(sonarGetLatestAltitude(), SONAR_OUT_OF_RANGE); // Check distance at various roll angles // distance 400, 5 degrees of roll EXPECT_EQ(sonarCalculateAltitude(400, 50, 0), 398); EXPECT_EQ(sonarGetLatestAltitude(), 398); // distance 400, 10 degrees of roll EXPECT_EQ(sonarCalculateAltitude(400, 100, 0), 393); EXPECT_EQ(sonarGetLatestAltitude(), 393); // distance 400, 15 degrees of roll, this corresponds to HC-SR04 specified max detection angle EXPECT_EQ(sonarCalculateAltitude(400, 150, 0), 386); EXPECT_EQ(sonarGetLatestAltitude(), 386); // distance 400, 20 degrees of roll EXPECT_EQ(sonarCalculateAltitude(400, 200, 0), 375); EXPECT_EQ(sonarGetLatestAltitude(), 375); // distance 400, 22.5 degrees of roll, this corresponds to HC-SR04 effective max detection angle EXPECT_EQ(sonarCalculateAltitude(400, 225, 0), 369); EXPECT_EQ(sonarGetLatestAltitude(), 369); // max range, max tilt EXPECT_EQ(sonarCalculateAltitude(sonarMaxRangeCm, sonarMaxTiltDeciDegrees, 0), sonarMaxAltWithTiltCm); EXPECT_EQ(sonarGetLatestAltitude(), sonarMaxAltWithTiltCm); } typedef struct rollAndPitch_s { // absolute angle inclination in multiple of 0.1 degree (deci degrees): 180 degrees = 1800 int16_t rollDeciDegrees; int16_t pitchDeciDegrees; } rollAndPitch_t; typedef struct inclinationAngleExpectations_s { rollAndPitch_t inclination; int16_t expected_angle; } inclinationAngleExpectations_t; TEST(SonarUnittest, TestCalculateTiltAngle) { const int testCount = 9; inclinationAngleExpectations_t inclinationAngleExpectations[testCount] = { { { 0, 0}, 0}, { { 1, 0}, 1}, { { 0, 1}, 1}, { { 0, -1}, 1}, { {-1, 0}, 1}, { {-1, -2}, 2}, { {-2, -1}, 2}, { { 1, 2}, 2}, { { 2, 1}, 2} }; rollAndPitch_t inclination = {0, 0}; int tilt_angle = sonarCalculateTiltAngle(inclination.rollDeciDegrees, inclination.pitchDeciDegrees); EXPECT_EQ(tilt_angle, 0); for (int i = 0; i < testCount; i++) { inclinationAngleExpectations_t *expectation = &inclinationAngleExpectations[i]; int result = sonarCalculateTiltAngle(expectation->inclination.rollDeciDegrees, expectation->inclination.pitchDeciDegrees); EXPECT_EQ(expectation->expected_angle, result); } } // STUBS extern "C" { void sensorsSet(uint32_t mask) {UNUSED(mask);} }