Руслан Урядинский / libuavcan

Dependents:   UAVCAN UAVCAN_Subscriber

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers param_server.cpp Source File

param_server.cpp

00001 /*
00002  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
00003  */
00004 
00005 #include <map>
00006 #include <gtest/gtest.h>
00007 #include <uavcan/protocol/param_server.hpp>
00008 #include "helpers.hpp"
00009 
00010 struct ParamServerTestManager : public uavcan::IParamManager
00011 {
00012     typedef std::map<std::string, double> KeyValue;
00013     KeyValue kv;
00014 
00015     virtual void getParamNameByIndex(Index index, Name& out_name) const
00016     {
00017         Index current_idx = 0;
00018         for (KeyValue::const_iterator it = kv.begin(); it != kv.end(); ++it, ++current_idx)
00019         {
00020             if (current_idx == index)
00021             {
00022                 out_name = it->first.c_str();
00023                 break;
00024             }
00025         }
00026     }
00027 
00028     virtual void assignParamValue(const Name& name, const Value& value)
00029     {
00030         assert(!name.empty());
00031         std::cout << "ASSIGN [" << name.c_str() << "]\n" << value << "\n---" << std::endl;
00032         KeyValue::iterator it = kv.find(name.c_str());
00033         if (it != kv.end())
00034         {
00035             if (value.is(Value::Tag::boolean_value))
00036             {
00037                 assert(value.getTag() == Value::Tag::boolean_value);
00038                 it->second = double(value.boolean_value);
00039             }
00040             else if (value.is(Value::Tag::integer_value))
00041             {
00042                 assert(value.getTag() == Value::Tag::integer_value);
00043                 it->second = double(value.integer_value);
00044             }
00045             else if (value.is(Value::Tag::real_value))
00046             {
00047                 assert(value.getTag() == Value::Tag::real_value);
00048                 it->second = double(value.real_value);
00049             }
00050             else if (value.is(Value::Tag::string_value))
00051             {
00052                 assert(value.getTag() == Value::Tag::string_value);
00053                 it->second = std::atof(value.string_value.c_str());
00054             }
00055             else
00056             {
00057                 assert(0);
00058             }
00059         }
00060     }
00061 
00062     virtual void readParamValue(const Name& name, Value& out_value) const
00063     {
00064         assert(!name.empty());
00065         KeyValue::const_iterator it = kv.find(name.c_str());
00066         if (it != kv.end())
00067         {
00068             out_value.to<Value::Tag::real_value>() = float(it->second);
00069             assert(out_value.getTag() == Value::Tag::real_value);
00070         }
00071         std::cout << "READ [" << name.c_str() << "]\n" << out_value << "\n---" << std::endl;
00072     }
00073 
00074     virtual int saveAllParams()
00075     {
00076         std::cout << "SAVE" << std::endl;
00077         return 0;
00078     }
00079 
00080     virtual int eraseAllParams()
00081     {
00082         std::cout << "ERASE" << std::endl;
00083         return 0;
00084     }
00085 };
00086 
00087 
00088 template <typename Client, typename Message>
00089 static void doCall(Client& client, const Message& request, InterlinkedTestNodesWithSysClock& nodes)
00090 {
00091     ASSERT_LE(0, client.call(1, request));
00092     ASSERT_LE(0, nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10)));
00093     ASSERT_TRUE(client.collector.result.get());
00094     ASSERT_TRUE(client.collector.result->isSuccessful());
00095 }
00096 
00097 
00098 TEST(ParamServer, Basic)
00099 {
00100     InterlinkedTestNodesWithSysClock nodes;
00101 
00102     uavcan::ParamServer server(nodes.a);
00103 
00104     ParamServerTestManager mgr;
00105 
00106     uavcan::GlobalDataTypeRegistry::instance().reset();
00107     uavcan::DefaultDataTypeRegistrator<uavcan::protocol::param::GetSet> _reg1;
00108     uavcan::DefaultDataTypeRegistrator<uavcan::protocol::param::ExecuteOpcode> _reg2;
00109 
00110     ASSERT_LE(0, server.start(&mgr));
00111 
00112     ServiceClientWithCollector<uavcan::protocol::param::GetSet> get_set_cln(nodes.b);
00113     ServiceClientWithCollector<uavcan::protocol::param::ExecuteOpcode> save_erase_cln(nodes.b);
00114 
00115     /*
00116      * Save/erase
00117      */
00118     uavcan::protocol::param::ExecuteOpcode::Request save_erase_rq;
00119     save_erase_rq.opcode = uavcan::protocol::param::ExecuteOpcode::Request::OPCODE_SAVE;
00120     doCall(save_erase_cln, save_erase_rq, nodes);
00121     ASSERT_TRUE(save_erase_cln.collector.result.get());
00122     ASSERT_TRUE(save_erase_cln.collector.result->getResponse().ok);
00123 
00124     save_erase_rq.opcode = uavcan::protocol::param::ExecuteOpcode::Request::OPCODE_ERASE;
00125     doCall(save_erase_cln, save_erase_rq, nodes);
00126     ASSERT_TRUE(save_erase_cln.collector.result->getResponse().ok);
00127 
00128     // Invalid opcode
00129     save_erase_rq.opcode = 0xFF;
00130     doCall(save_erase_cln, save_erase_rq, nodes);
00131     ASSERT_FALSE(save_erase_cln.collector.result->getResponse().ok);
00132 
00133     /*
00134      * Get/set
00135      */
00136     uavcan::protocol::param::GetSet::Request get_set_rq;
00137     get_set_rq.name = "nonexistent_parameter";
00138     doCall(get_set_cln, get_set_rq, nodes);
00139     ASSERT_TRUE(get_set_cln.collector.result.get());
00140     ASSERT_TRUE(get_set_cln.collector.result->getResponse().name.empty());
00141 
00142     // No such variable, shall return empty name/value
00143     get_set_rq.index = 0;
00144     get_set_rq.name.clear();
00145     get_set_rq.value.to<uavcan::protocol::param::Value::Tag::integer_value>() = 0xDEADBEEF;
00146     doCall(get_set_cln, get_set_rq, nodes);
00147     ASSERT_TRUE(get_set_cln.collector.result->getResponse().name.empty());
00148     ASSERT_TRUE(get_set_cln.collector.result->getResponse().value.is(uavcan::protocol::param::Value::Tag::empty));
00149 
00150     mgr.kv["foobar"] = 123.456;    // New param
00151 
00152     // Get by name
00153     get_set_rq = uavcan::protocol::param::GetSet::Request();
00154     get_set_rq.name = "foobar";
00155     doCall(get_set_cln, get_set_rq, nodes);
00156     ASSERT_STREQ("foobar", get_set_cln.collector.result->getResponse().name.c_str());
00157     ASSERT_TRUE(get_set_cln.collector.result->getResponse().value.is(uavcan::protocol::param::Value::Tag::real_value));
00158     ASSERT_FLOAT_EQ(123.456F, get_set_cln.collector.result->getResponse().value.
00159                               to<uavcan::protocol::param::Value::Tag::real_value>());
00160 
00161     // Set by index
00162     get_set_rq = uavcan::protocol::param::GetSet::Request();
00163     get_set_rq.index = 0;
00164     get_set_rq.value.to<uavcan::protocol::param::Value::Tag::string_value>() = "424242";
00165     doCall(get_set_cln, get_set_rq, nodes);
00166     ASSERT_STREQ("foobar", get_set_cln.collector.result->getResponse().name.c_str());
00167     ASSERT_FLOAT_EQ(424242, get_set_cln.collector.result->getResponse().value.
00168                             to<uavcan::protocol::param::Value::Tag::real_value>());
00169 
00170     // Get by index
00171     get_set_rq = uavcan::protocol::param::GetSet::Request();
00172     get_set_rq.index = 0;
00173     doCall(get_set_cln, get_set_rq, nodes);
00174     ASSERT_STREQ("foobar", get_set_cln.collector.result->getResponse().name.c_str());
00175     ASSERT_FLOAT_EQ(424242, get_set_cln.collector.result->getResponse().value.
00176                             to<uavcan::protocol::param::Value::Tag::real_value>());
00177 }