test_time_sync.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
  3. */
  4. #include <iostream>
  5. #include <cassert>
  6. #include <uavcan_linux/uavcan_linux.hpp>
  7. #include <uavcan/protocol/global_time_sync_master.hpp>
  8. #include <uavcan/protocol/global_time_sync_slave.hpp>
  9. #include "debug.hpp"
  10. static uavcan_linux::NodePtr initNode(const std::vector<std::string>& ifaces, uavcan::NodeID nid,
  11. const std::string& name)
  12. {
  13. auto node = uavcan_linux::makeNode(ifaces);
  14. node->setNodeID(nid);
  15. node->setName(name.c_str());
  16. ENFORCE(0 == node->start());
  17. node->setModeOperational();
  18. return node;
  19. }
  20. static void runForever(const uavcan_linux::NodePtr& node)
  21. {
  22. uavcan::GlobalTimeSyncMaster tsmaster(*node);
  23. ENFORCE(0 == tsmaster.init());
  24. uavcan::GlobalTimeSyncSlave tsslave(*node);
  25. ENFORCE(0 == tsslave.start());
  26. auto publish_sync_if_master = [&](const uavcan::TimerEvent&)
  27. {
  28. bool i_am_master = false;
  29. if (tsslave.isActive())
  30. {
  31. const uavcan::NodeID master_node = tsslave.getMasterNodeID();
  32. assert(master_node.isValid());
  33. if (node->getNodeID() < master_node)
  34. {
  35. std::cout << "Overriding the lower priority master " << int(master_node.get()) << std::endl;
  36. i_am_master = true;
  37. }
  38. else
  39. {
  40. std::cout << "There is other master of higher priority " << int(master_node.get()) << std::endl;
  41. }
  42. }
  43. else
  44. {
  45. std::cout << "No other masters present" << std::endl;
  46. i_am_master = true;
  47. }
  48. // Don't forget to disable slave adjustments if we're master
  49. tsslave.suppress(i_am_master);
  50. if (i_am_master)
  51. {
  52. ENFORCE(0 <= tsmaster.publish());
  53. }
  54. };
  55. auto sync_publish_timer = node->makeTimer(uavcan::MonotonicDuration::fromMSec(1000), publish_sync_if_master);
  56. while (true)
  57. {
  58. const int res = node->spin(uavcan::MonotonicDuration::getInfinite());
  59. if (res < 0)
  60. {
  61. node->logError("spin", "Error %*", res);
  62. }
  63. }
  64. }
  65. int main(int argc, const char** argv)
  66. {
  67. try
  68. {
  69. if (argc < 3)
  70. {
  71. std::cerr << "Usage:\n\t" << argv[0] << " <node-id> <can-iface-name-1> [can-iface-name-N...]" << std::endl;
  72. return 1;
  73. }
  74. const int self_node_id = std::stoi(argv[1]);
  75. std::vector<std::string> iface_names;
  76. for (int i = 2; i < argc; i++)
  77. {
  78. iface_names.emplace_back(argv[i]);
  79. }
  80. uavcan_linux::NodePtr node = initNode(iface_names, self_node_id, "org.uavcan.linux_test_node_status_monitor");
  81. runForever(node);
  82. return 0;
  83. }
  84. catch (const std::exception& ex)
  85. {
  86. std::cerr << "Exception: " << ex.what() << std::endl;
  87. return 1;
  88. }
  89. }