AP: fix erroneous warning with Monostable FlipFlip
Add a unit-test written by Huntely, and extend the AP configure code, so the 'time' config of monostables doesn't trigger an incorrect warning in the console / logs. Thanks to Huntley Palmer for pointing this out. SF-ID: https://sourceforge.net/p/flightgear/codetickets/2812/
This commit is contained in:
parent
87029295c1
commit
c54fba1095
7 changed files with 184 additions and 7 deletions
src/Autopilot
test_suite/unit_tests/Autopilot
|
@ -52,12 +52,12 @@ bool Component::configure( SGPropertyNode& prop_root,
|
|||
if( !configure(*child, cname, prop_root)
|
||||
&& cname != "params" ) // 'params' is usually used to specify parameters
|
||||
// in PropertList files.
|
||||
SG_LOG
|
||||
(
|
||||
SG_AUTOPILOT,
|
||||
SG_INFO,
|
||||
"Component::configure: unknown node: " << cname
|
||||
);
|
||||
|
||||
// consider using the error reporting mechanism here, at level warning
|
||||
SG_LOG(
|
||||
SG_AUTOPILOT,
|
||||
SG_DEV_WARN,
|
||||
"Component::configure: unknown node: " << cname);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -269,6 +269,12 @@ protected:
|
|||
SGPropertyNode& prop_root );
|
||||
InputValueList _time;
|
||||
double _t;
|
||||
|
||||
bool isConfigProperty(const std::string& cfg_name) const override
|
||||
{
|
||||
return cfg_name == "time";
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief constructor for a MonoFlopImplementation
|
||||
|
@ -457,6 +463,12 @@ bool FlipFlop::configure( SGPropertyNode& cfg_node,
|
|||
return true;
|
||||
}
|
||||
|
||||
if (_implementation && _implementation->isConfigProperty(cfg_name)) {
|
||||
// componentForge CreateAndConfigureFunctor<> already called configure with all the nodes
|
||||
// on our implementation, but we need to ensure we don't return false here for such nodes
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,8 @@ public:
|
|||
*/
|
||||
bool configure( SGPropertyNode& prop_root,
|
||||
SGPropertyNode& cfg );
|
||||
|
||||
virtual bool isConfigProperty(const std::string& cfg_name) const { return false; }
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,6 +5,7 @@ set(TESTSUITE_SOURCES
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/testPidController.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/testPidControllerData.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/testInputValue.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/testMonostable.cxx
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
|
@ -14,5 +15,6 @@ set(TESTSUITE_HEADERS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/testPidController.hxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/testPidControllerData.hxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/testInputValue.hxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/testMonostable.hxx
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
|
|
@ -18,10 +18,12 @@
|
|||
*/
|
||||
|
||||
#include "testDigitalFilter.hxx"
|
||||
#include "testPidController.hxx"
|
||||
#include "testInputValue.hxx"
|
||||
#include "testMonostable.hxx"
|
||||
#include "testPidController.hxx"
|
||||
|
||||
// Set up the unit tests.
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(MonostableTests, "Unit tests");
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(DigitalFilterTests, "Unit tests");
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(PidControllerTests, "Unit tests");
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(InputValueTests, "Unit tests");
|
||||
|
|
122
test_suite/unit_tests/Autopilot/testMonostable.cxx
Normal file
122
test_suite/unit_tests/Autopilot/testMonostable.cxx
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* SPDX-FileName: testMonostable.cxx
|
||||
* SPDX-FileComment: Unit tests for monostable autopilot element
|
||||
* SPDX-FileCopyrightText: Copyright (C) 2023 Huntley Palmer
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "testMonostable.hxx"
|
||||
|
||||
#include <strstream>
|
||||
|
||||
#include "test_suite/FGTestApi/testGlobals.hxx"
|
||||
|
||||
|
||||
#include <Autopilot/autopilot.hxx>
|
||||
#include <Autopilot/digitalfilter.hxx>
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <Main/globals.hxx>
|
||||
|
||||
|
||||
#include <simgear/math/sg_random.hxx>
|
||||
#include <simgear/props/props_io.hxx>
|
||||
|
||||
// Set up function for each test.
|
||||
void MonostableTests::setUp()
|
||||
{
|
||||
FGTestApi::setUp::initTestGlobals("ap-monostable");
|
||||
}
|
||||
|
||||
|
||||
// Clean up after each test.
|
||||
void MonostableTests::tearDown()
|
||||
{
|
||||
FGTestApi::tearDown::shutdownTestGlobals();
|
||||
}
|
||||
|
||||
|
||||
SGPropertyNode_ptr MonostableTests::configFromString(const std::string& s)
|
||||
{
|
||||
SGPropertyNode_ptr config = new SGPropertyNode;
|
||||
|
||||
std::istringstream iss(s);
|
||||
readProperties(iss, config);
|
||||
return config;
|
||||
}
|
||||
|
||||
void MonostableTests::testMonostable()
|
||||
{
|
||||
sg_srandom(999);
|
||||
//
|
||||
// Simple monostable from wiki:
|
||||
// monostable stable state is false, true when Set, until timeout
|
||||
// ( S == False, test/S == 0 ) : O/P = 0
|
||||
// ( S == True , test/S == 1 ) : O/P = 1
|
||||
// ( S == False, test/S == 0 ) : Timer running, O/P = 1
|
||||
// ( S == False, test/S == 0 ) : Timed out , O/P = 0
|
||||
//
|
||||
//
|
||||
auto config = configFromString(R"(<?xml version="1.0" encoding="UTF-8"?>
|
||||
<PropertyList>
|
||||
<flipflop>
|
||||
<type>monostable</type>
|
||||
<S>
|
||||
<property>/test/S</property>
|
||||
</S>
|
||||
<time>
|
||||
<value>0.50</value>
|
||||
</time>
|
||||
<output>/test/Q</output>
|
||||
</flipflop>
|
||||
</PropertyList>
|
||||
)");
|
||||
|
||||
auto ap = new FGXMLAutopilot::Autopilot(globals->get_props(), config);
|
||||
|
||||
globals->get_subsystem_mgr()->add("ap", ap);
|
||||
ap->bind();
|
||||
ap->init();
|
||||
|
||||
// Initially test/S is 0 O/P s.b stable state == 0
|
||||
fgSetBool("/test/S", false);
|
||||
ap->update(0.01);
|
||||
CPPUNIT_ASSERT_EQUAL(false, fgGetBool("/test/Q"));
|
||||
|
||||
// steady input test/S = 0 s.b. no change
|
||||
ap->update(0.24);
|
||||
CPPUNIT_ASSERT_EQUAL(false, fgGetBool("/test/Q"));
|
||||
|
||||
// steady test/S = 0 s.b. no change during timer
|
||||
ap->update(0.25);
|
||||
CPPUNIT_ASSERT_EQUAL(false, fgGetBool("/test/Q"));
|
||||
|
||||
// steady test/S = 0 s.b. no change after timeout
|
||||
ap->update(0.25);
|
||||
CPPUNIT_ASSERT_EQUAL(false, fgGetBool("/test/Q"));
|
||||
|
||||
// Set S input true == 1 O/P should immediately = 1, true
|
||||
fgSetBool("/test/S", true);
|
||||
ap->update(0.01);
|
||||
CPPUNIT_ASSERT_EQUAL(true, fgGetBool("/test/Q"));
|
||||
|
||||
// steady test/S = 1 s.b. no change during timer
|
||||
ap->update(0.24);
|
||||
CPPUNIT_ASSERT_EQUAL(true, fgGetBool("/test/Q"));
|
||||
|
||||
// steady test/S = 1 s.b. no change after timeout
|
||||
ap->update(0.25);
|
||||
CPPUNIT_ASSERT_EQUAL(true, fgGetBool("/test/Q"));
|
||||
|
||||
// Reset Input test/S = 0 s.b. no change
|
||||
fgSetBool("/test/S", false);
|
||||
ap->update(0.01);
|
||||
CPPUNIT_ASSERT_EQUAL(true, fgGetBool("/test/Q"));
|
||||
|
||||
// steady test/S = 0 s.b. no change during timer
|
||||
ap->update(0.24);
|
||||
CPPUNIT_ASSERT_EQUAL(true, fgGetBool("/test/Q"));
|
||||
|
||||
// steady test/S = 0 O/P resets = 0 after timeout
|
||||
ap->update(0.25);
|
||||
CPPUNIT_ASSERT_EQUAL(false, fgGetBool("/test/Q"));
|
||||
}
|
37
test_suite/unit_tests/Autopilot/testMonostable.hxx
Normal file
37
test_suite/unit_tests/Autopilot/testMonostable.hxx
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* SPDX-FileName: testMonostable.hxx
|
||||
* SPDX-FileComment: Unit tests for monostable autopilot element
|
||||
* SPDX-FileCopyrightText: Copyright (C) 2023 Huntley Palmer
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <cppunit/TestFixture.h>
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
#include <simgear/props/props.hxx>
|
||||
|
||||
|
||||
// The system tests.
|
||||
class MonostableTests : public CppUnit::TestFixture
|
||||
{
|
||||
// Set up the test suite.
|
||||
CPPUNIT_TEST_SUITE(MonostableTests);
|
||||
CPPUNIT_TEST(testMonostable);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
SGPropertyNode_ptr configFromString(const std::string& s);
|
||||
|
||||
public:
|
||||
// Set up function for each test.
|
||||
void setUp();
|
||||
|
||||
// Clean up after each test.
|
||||
void tearDown();
|
||||
|
||||
|
||||
// The tests.
|
||||
void testMonostable();
|
||||
};
|
Loading…
Add table
Reference in a new issue