param_server.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
  3. */
  4. #include <map>
  5. #include <gtest/gtest.h>
  6. #include <uavcan/protocol/param_server.hpp>
  7. #include "helpers.hpp"
  8. struct ParamServerTestManager : public uavcan::IParamManager
  9. {
  10. typedef std::map<std::string, double> KeyValue;
  11. KeyValue kv;
  12. virtual void getParamNameByIndex(Index index, Name& out_name) const
  13. {
  14. Index current_idx = 0;
  15. for (KeyValue::const_iterator it = kv.begin(); it != kv.end(); ++it, ++current_idx)
  16. {
  17. if (current_idx == index)
  18. {
  19. out_name = it->first.c_str();
  20. break;
  21. }
  22. }
  23. }
  24. virtual void assignParamValue(const Name& name, const Value& value)
  25. {
  26. assert(!name.empty());
  27. std::cout << "ASSIGN [" << name.c_str() << "]\n" << value << "\n---" << std::endl;
  28. KeyValue::iterator it = kv.find(name.c_str());
  29. if (it != kv.end())
  30. {
  31. if (value.is(Value::Tag::boolean_value))
  32. {
  33. assert(value.getTag() == Value::Tag::boolean_value);
  34. it->second = double(value.boolean_value);
  35. }
  36. else if (value.is(Value::Tag::integer_value))
  37. {
  38. assert(value.getTag() == Value::Tag::integer_value);
  39. it->second = double(value.integer_value);
  40. }
  41. else if (value.is(Value::Tag::real_value))
  42. {
  43. assert(value.getTag() == Value::Tag::real_value);
  44. it->second = double(value.real_value);
  45. }
  46. else if (value.is(Value::Tag::string_value))
  47. {
  48. assert(value.getTag() == Value::Tag::string_value);
  49. it->second = std::atof(value.string_value.c_str());
  50. }
  51. else
  52. {
  53. assert(0);
  54. }
  55. }
  56. }
  57. virtual void readParamValue(const Name& name, Value& out_value) const
  58. {
  59. assert(!name.empty());
  60. KeyValue::const_iterator it = kv.find(name.c_str());
  61. if (it != kv.end())
  62. {
  63. out_value.to<Value::Tag::real_value>() = float(it->second);
  64. assert(out_value.getTag() == Value::Tag::real_value);
  65. }
  66. std::cout << "READ [" << name.c_str() << "]\n" << out_value << "\n---" << std::endl;
  67. }
  68. virtual int saveAllParams()
  69. {
  70. std::cout << "SAVE" << std::endl;
  71. return 0;
  72. }
  73. virtual int eraseAllParams()
  74. {
  75. std::cout << "ERASE" << std::endl;
  76. return 0;
  77. }
  78. };
  79. template <typename Client, typename Message>
  80. static void doCall(Client& client, const Message& request, InterlinkedTestNodesWithSysClock& nodes)
  81. {
  82. ASSERT_LE(0, client.call(1, request));
  83. ASSERT_LE(0, nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10)));
  84. ASSERT_TRUE(client.collector.result.get());
  85. ASSERT_TRUE(client.collector.result->isSuccessful());
  86. }
  87. TEST(ParamServer, Basic)
  88. {
  89. InterlinkedTestNodesWithSysClock nodes;
  90. uavcan::ParamServer server(nodes.a);
  91. ParamServerTestManager mgr;
  92. uavcan::GlobalDataTypeRegistry::instance().reset();
  93. uavcan::DefaultDataTypeRegistrator<uavcan::protocol::param::GetSet> _reg1;
  94. uavcan::DefaultDataTypeRegistrator<uavcan::protocol::param::ExecuteOpcode> _reg2;
  95. ASSERT_LE(0, server.start(&mgr));
  96. ServiceClientWithCollector<uavcan::protocol::param::GetSet> get_set_cln(nodes.b);
  97. ServiceClientWithCollector<uavcan::protocol::param::ExecuteOpcode> save_erase_cln(nodes.b);
  98. /*
  99. * Save/erase
  100. */
  101. uavcan::protocol::param::ExecuteOpcode::Request save_erase_rq;
  102. save_erase_rq.opcode = uavcan::protocol::param::ExecuteOpcode::Request::OPCODE_SAVE;
  103. doCall(save_erase_cln, save_erase_rq, nodes);
  104. ASSERT_TRUE(save_erase_cln.collector.result.get());
  105. ASSERT_TRUE(save_erase_cln.collector.result->getResponse().ok);
  106. save_erase_rq.opcode = uavcan::protocol::param::ExecuteOpcode::Request::OPCODE_ERASE;
  107. doCall(save_erase_cln, save_erase_rq, nodes);
  108. ASSERT_TRUE(save_erase_cln.collector.result->getResponse().ok);
  109. // Invalid opcode
  110. save_erase_rq.opcode = 0xFF;
  111. doCall(save_erase_cln, save_erase_rq, nodes);
  112. ASSERT_FALSE(save_erase_cln.collector.result->getResponse().ok);
  113. /*
  114. * Get/set
  115. */
  116. uavcan::protocol::param::GetSet::Request get_set_rq;
  117. get_set_rq.name = "nonexistent_parameter";
  118. doCall(get_set_cln, get_set_rq, nodes);
  119. ASSERT_TRUE(get_set_cln.collector.result.get());
  120. ASSERT_TRUE(get_set_cln.collector.result->getResponse().name.empty());
  121. // No such variable, shall return empty name/value
  122. get_set_rq.index = 0;
  123. get_set_rq.name.clear();
  124. get_set_rq.value.to<uavcan::protocol::param::Value::Tag::integer_value>() = 0xDEADBEEF;
  125. doCall(get_set_cln, get_set_rq, nodes);
  126. ASSERT_TRUE(get_set_cln.collector.result->getResponse().name.empty());
  127. ASSERT_TRUE(get_set_cln.collector.result->getResponse().value.is(uavcan::protocol::param::Value::Tag::empty));
  128. mgr.kv["foobar"] = 123.456; // New param
  129. // Get by name
  130. get_set_rq = uavcan::protocol::param::GetSet::Request();
  131. get_set_rq.name = "foobar";
  132. doCall(get_set_cln, get_set_rq, nodes);
  133. ASSERT_STREQ("foobar", get_set_cln.collector.result->getResponse().name.c_str());
  134. ASSERT_TRUE(get_set_cln.collector.result->getResponse().value.is(uavcan::protocol::param::Value::Tag::real_value));
  135. ASSERT_FLOAT_EQ(123.456F, get_set_cln.collector.result->getResponse().value.
  136. to<uavcan::protocol::param::Value::Tag::real_value>());
  137. // Set by index
  138. get_set_rq = uavcan::protocol::param::GetSet::Request();
  139. get_set_rq.index = 0;
  140. get_set_rq.value.to<uavcan::protocol::param::Value::Tag::string_value>() = "424242";
  141. doCall(get_set_cln, get_set_rq, nodes);
  142. ASSERT_STREQ("foobar", get_set_cln.collector.result->getResponse().name.c_str());
  143. ASSERT_FLOAT_EQ(424242, get_set_cln.collector.result->getResponse().value.
  144. to<uavcan::protocol::param::Value::Tag::real_value>());
  145. // Get by index
  146. get_set_rq = uavcan::protocol::param::GetSet::Request();
  147. get_set_rq.index = 0;
  148. doCall(get_set_cln, get_set_rq, nodes);
  149. ASSERT_STREQ("foobar", get_set_cln.collector.result->getResponse().name.c_str());
  150. ASSERT_FLOAT_EQ(424242, get_set_cln.collector.result->getResponse().value.
  151. to<uavcan::protocol::param::Value::Tag::real_value>());
  152. }