mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-04-14 10:07:39 +08:00
166 lines
5.6 KiB
C++
166 lines
5.6 KiB
C++
/*
|
|
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
|
|
*/
|
|
|
|
#include <map>
|
|
#include <gtest/gtest.h>
|
|
#include <uavcan/protocol/param_server.hpp>
|
|
#include "helpers.hpp"
|
|
|
|
struct ParamServerTestManager : public uavcan::IParamManager
|
|
{
|
|
typedef std::map<std::string, double> KeyValue;
|
|
KeyValue kv;
|
|
|
|
virtual void getParamNameByIndex(ParamIndex index, ParamName& out_name) const
|
|
{
|
|
ParamIndex current_idx = 0;
|
|
for (KeyValue::const_iterator it = kv.begin(); it != kv.end(); ++it, ++current_idx)
|
|
{
|
|
if (current_idx == index)
|
|
{
|
|
out_name = it->first.c_str();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual void assignParamValue(const ParamName& name, const ParamValue& value)
|
|
{
|
|
std::cout << "ASSIGN [" << name.c_str() << "]\n" << value << "\n---" << std::endl;
|
|
KeyValue::iterator it = kv.find(name.c_str());
|
|
if (it != kv.end())
|
|
{
|
|
if (!value.value_bool.empty())
|
|
{
|
|
it->second = double(value.value_bool[0]);
|
|
}
|
|
else if (!value.value_int.empty())
|
|
{
|
|
it->second = double(value.value_int[0]);
|
|
}
|
|
else if (!value.value_float.empty())
|
|
{
|
|
it->second = double(value.value_float[0]);
|
|
}
|
|
else
|
|
{
|
|
assert(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual void readParamValue(const ParamName& name, ParamValue& out_value) const
|
|
{
|
|
KeyValue::const_iterator it = kv.find(name.c_str());
|
|
if (it != kv.end())
|
|
{
|
|
out_value.value_float.push_back(float(it->second));
|
|
}
|
|
std::cout << "READ [" << name.c_str() << "]\n" << out_value << "\n---" << std::endl;
|
|
}
|
|
|
|
virtual int saveAllParams()
|
|
{
|
|
std::cout << "SAVE" << std::endl;
|
|
return 0;
|
|
}
|
|
|
|
virtual int eraseAllParams()
|
|
{
|
|
std::cout << "ERASE" << std::endl;
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
|
|
template <typename Client, typename Message>
|
|
static void doCall(Client& client, const Message& request, InterlinkedTestNodesWithSysClock& nodes)
|
|
{
|
|
ASSERT_LE(0, client.call(1, request));
|
|
ASSERT_LE(0, nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10)));
|
|
ASSERT_TRUE(client.collector.result->isSuccessful());
|
|
}
|
|
|
|
|
|
TEST(ParamServer, Basic)
|
|
{
|
|
InterlinkedTestNodesWithSysClock nodes;
|
|
|
|
uavcan::ParamServer server(nodes.a);
|
|
|
|
ParamServerTestManager mgr;
|
|
|
|
uavcan::GlobalDataTypeRegistry::instance().reset();
|
|
uavcan::DefaultDataTypeRegistrator<uavcan::protocol::param::GetSet> _reg1;
|
|
uavcan::DefaultDataTypeRegistrator<uavcan::protocol::param::SaveErase> _reg2;
|
|
|
|
ASSERT_LE(0, server.start(&mgr));
|
|
|
|
ServiceClientWithCollector<uavcan::protocol::param::GetSet> get_set_cln(nodes.b);
|
|
ServiceClientWithCollector<uavcan::protocol::param::SaveErase> save_erase_cln(nodes.b);
|
|
|
|
/*
|
|
* Save/erase
|
|
*/
|
|
uavcan::protocol::param::SaveErase::Request save_erase_rq;
|
|
save_erase_rq.opcode = uavcan::protocol::param::SaveErase::Request::OPCODE_SAVE;
|
|
doCall(save_erase_cln, save_erase_rq, nodes);
|
|
ASSERT_TRUE(save_erase_cln.collector.result.get());
|
|
ASSERT_TRUE(save_erase_cln.collector.result->response.ok);
|
|
|
|
save_erase_rq.opcode = uavcan::protocol::param::SaveErase::Request::OPCODE_ERASE;
|
|
doCall(save_erase_cln, save_erase_rq, nodes);
|
|
ASSERT_TRUE(save_erase_cln.collector.result->response.ok);
|
|
|
|
// Invalid opcode
|
|
save_erase_rq.opcode = 0xFF;
|
|
doCall(save_erase_cln, save_erase_rq, nodes);
|
|
ASSERT_FALSE(save_erase_cln.collector.result->response.ok);
|
|
|
|
/*
|
|
* Get/set
|
|
*/
|
|
uavcan::protocol::param::GetSet::Request get_set_rq;
|
|
get_set_rq.name = "nonexistent_parameter";
|
|
doCall(get_set_cln, get_set_rq, nodes);
|
|
ASSERT_TRUE(get_set_cln.collector.result.get());
|
|
ASSERT_TRUE(get_set_cln.collector.result->response.name.empty());
|
|
|
|
// No such variable, shall return empty name/value
|
|
get_set_rq.index = 0;
|
|
get_set_rq.name.clear();
|
|
get_set_rq.value.value_int.push_back(0xDEADBEEF);
|
|
doCall(get_set_cln, get_set_rq, nodes);
|
|
ASSERT_TRUE(get_set_cln.collector.result->response.name.empty());
|
|
ASSERT_TRUE(get_set_cln.collector.result->response.value.value_bool.empty());
|
|
ASSERT_TRUE(get_set_cln.collector.result->response.value.value_int.empty());
|
|
ASSERT_TRUE(get_set_cln.collector.result->response.value.value_float.empty());
|
|
|
|
mgr.kv["foobar"] = 123.456; // New param
|
|
|
|
// Get by name
|
|
get_set_rq = uavcan::protocol::param::GetSet::Request();
|
|
get_set_rq.name = "foobar";
|
|
doCall(get_set_cln, get_set_rq, nodes);
|
|
ASSERT_STREQ("foobar", get_set_cln.collector.result->response.name.c_str());
|
|
ASSERT_TRUE(get_set_cln.collector.result->response.value.value_bool.empty());
|
|
ASSERT_TRUE(get_set_cln.collector.result->response.value.value_int.empty());
|
|
ASSERT_FLOAT_EQ(123.456F, get_set_cln.collector.result->response.value.value_float[0]);
|
|
|
|
// Set by index
|
|
get_set_rq = uavcan::protocol::param::GetSet::Request();
|
|
get_set_rq.index = 0;
|
|
get_set_rq.value.value_int.push_back(424242);
|
|
doCall(get_set_cln, get_set_rq, nodes);
|
|
ASSERT_STREQ("foobar", get_set_cln.collector.result->response.name.c_str());
|
|
ASSERT_FLOAT_EQ(424242, get_set_cln.collector.result->response.value.value_float[0]);
|
|
|
|
// Get by index
|
|
get_set_rq = uavcan::protocol::param::GetSet::Request();
|
|
get_set_rq.index = 0;
|
|
doCall(get_set_cln, get_set_rq, nodes);
|
|
ASSERT_STREQ("foobar", get_set_cln.collector.result->response.name.c_str());
|
|
ASSERT_FLOAT_EQ(424242, get_set_cln.collector.result->response.value.value_float[0]);
|
|
}
|