uavcan_monitor.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #include <cstdio>
6 #include <bitset>
7 #include <unordered_map>
10 #include "debug.hpp"
11 
12 enum class CLIColor : unsigned
13 {
14  Red = 31,
15  Green = 32,
16  Yellow = 33,
17  Blue = 34,
18  Magenta = 35,
19  Cyan = 36,
20  White = 37,
21  Default = 39
22 };
23 
24 class CLIColorizer
25 {
27 public:
28  explicit CLIColorizer(CLIColor c) : color_(c)
29  {
30  std::printf("\033[%um", static_cast<unsigned>(color_));
31  }
32 
34  {
35  std::printf("\033[%um", static_cast<unsigned>(CLIColor::Default));
36  }
37 };
38 
40 {
42  std::unordered_map<int, uavcan::protocol::NodeStatus> status_registry_;
43 
45  {
46  status_registry_[msg.getSrcNodeID().get()] = msg;
47  }
48 
49  static std::pair<CLIColor, std::string> healthToColoredString(const std::uint8_t health)
50  {
51  static const std::unordered_map<std::uint8_t, std::pair<CLIColor, std::string>> map
52  {
53  { uavcan::protocol::NodeStatus::HEALTH_OK, { CLIColor(CLIColor::Green), "OK" }},
54  { uavcan::protocol::NodeStatus::HEALTH_WARNING, { CLIColor(CLIColor::Yellow), "WARNING" }},
55  { uavcan::protocol::NodeStatus::HEALTH_ERROR, { CLIColor(CLIColor::Magenta), "ERROR" }},
56  { uavcan::protocol::NodeStatus::HEALTH_CRITICAL, { CLIColor(CLIColor::Red), "CRITICAL" }}
57  };
58  try
59  {
60  return map.at(health);
61  }
62  catch (std::out_of_range&)
63  {
64  return { CLIColor(CLIColor::Red), std::to_string(health) };
65  }
66  }
67 
68  static std::pair<CLIColor, std::string> modeToColoredString(const std::uint8_t mode)
69  {
70  static const std::unordered_map<std::uint8_t, std::pair<CLIColor, std::string>> map
71  {
72  { uavcan::protocol::NodeStatus::MODE_OPERATIONAL, { CLIColor(CLIColor::Green), "OPERATIONAL" }},
73  { uavcan::protocol::NodeStatus::MODE_INITIALIZATION, { CLIColor(CLIColor::Yellow), "INITIALIZATION" }},
74  { uavcan::protocol::NodeStatus::MODE_MAINTENANCE, { CLIColor(CLIColor::Cyan), "MAINTENANCE" }},
75  { uavcan::protocol::NodeStatus::MODE_SOFTWARE_UPDATE, { CLIColor(CLIColor::Magenta), "SOFTWARE_UPDATE" }},
76  { uavcan::protocol::NodeStatus::MODE_OFFLINE, { CLIColor(CLIColor::Red), "OFFLINE" }}
77  };
78  try
79  {
80  return map.at(mode);
81  }
82  catch (std::out_of_range&)
83  {
84  return { CLIColor(CLIColor::Red), std::to_string(mode) };
85  }
86  }
87 
89  {
90  const auto health_and_color = healthToColoredString(status.health);
91  const auto mode_and_color = modeToColoredString(status.mode);
92 
93  const int nid_int = nid.get();
94  const unsigned long uptime = status_registry_[nid_int].uptime_sec;
95  const unsigned vendor_code = status_registry_[nid_int].vendor_specific_status_code;
96 
97  std::printf(" %-3d |", nid_int);
98  {
99  CLIColorizer clz(mode_and_color.first);
100  std::printf(" %-15s ", mode_and_color.second.c_str());
101  }
102  std::printf("|");
103  {
104  CLIColorizer clz(health_and_color.first);
105  std::printf(" %-8s ", health_and_color.second.c_str());
106  }
107  std::printf("| %-10lu | %04x %s'%s %u\n", uptime, vendor_code,
108  std::bitset<8>((vendor_code >> 8) & 0xFF).to_string().c_str(),
109  std::bitset<8>(vendor_code).to_string().c_str(),
110  vendor_code);
111  }
112 
114  {
115  std::printf("\x1b[1J"); // Clear screen from the current cursor position to the beginning
116  std::printf("\x1b[H"); // Move cursor to the coordinates 1,1
117  std::printf(" NID | Mode | Health | Uptime [s] | Vendor-specific status code\n");
118  std::printf("-----+-----------------+----------+------------+-hex---bin----------------dec--\n");
119 
120  for (unsigned i = 1; i <= uavcan::NodeID::Max; i++)
121  {
122  if (isNodeKnown(i))
123  {
125  }
126  }
127  }
128 
129 public:
132  , timer_(node->makeTimer(uavcan::MonotonicDuration::fromMSec(500),
133  std::bind(&Monitor::redraw, this, std::placeholders::_1)))
134  { }
135 };
136 
137 
138 static uavcan_linux::NodePtr initNodeInPassiveMode(const std::vector<std::string>& ifaces, const std::string& node_name)
139 {
140  auto node = uavcan_linux::makeNode(ifaces, node_name.c_str(),
141  uavcan::protocol::SoftwareVersion(), uavcan::protocol::HardwareVersion());
142  node->setModeOperational();
143  return node;
144 }
145 
147 {
148  Monitor mon(node);
149  ENFORCE(0 == mon.start());
150  while (true)
151  {
152  const int res = node->spin(uavcan::MonotonicDuration::getInfinite());
153  if (res < 0)
154  {
155  node->logError("spin", "Error %*", res);
156  }
157  }
158 }
159 
160 int main(int argc, const char** argv)
161 {
162  try
163  {
164  if (argc < 2)
165  {
166  std::cerr << "Usage:\n\t" << argv[0] << " <can-iface-name-1> [can-iface-name-N...]" << std::endl;
167  return 1;
168  }
169  std::vector<std::string> iface_names;
170  for (int i = 1; i < argc; i++)
171  {
172  iface_names.emplace_back(argv[i]);
173  }
174  uavcan_linux::NodePtr node = initNodeInPassiveMode(iface_names, "org.uavcan.linux_app.node_status_monitor");
175  runForever(node);
176  return 0;
177  }
178  catch (const std::exception& ex)
179  {
180  std::cerr << "Error: " << ex.what() << std::endl;
181  return 1;
182  }
183 }
CLIColor::White
@ White
CLIColor::Magenta
@ Magenta
CLIColor
CLIColor
Definition: uavcan_monitor.cpp:12
Monitor::handleNodeStatusMessage
void handleNodeStatusMessage(const uavcan::ReceivedDataStructure< uavcan::protocol::NodeStatus > &msg) override
Definition: uavcan_monitor.cpp:44
uavcan::NodeStatusMonitor::NodeStatus
Definition: node_status_monitor.hpp:25
uavcan::NodeID::get
uint8_t get() const
Definition: transfer.hpp:132
uavcan::NodeID
Definition: transfer.hpp:112
main
int main(int argc, const char **argv)
Definition: uavcan_monitor.cpp:160
CLIColor::Yellow
@ Yellow
CLIColorizer::~CLIColorizer
~CLIColorizer()
Definition: uavcan_monitor.cpp:33
uavcan::ReceivedDataStructure
Definition: generic_subscriber.hpp:39
Monitor::status_registry_
std::unordered_map< int, uavcan::protocol::NodeStatus > status_registry_
Definition: uavcan_monitor.cpp:42
CLIColorizer::color_
const CLIColor color_
Definition: uavcan_monitor.cpp:26
uavcan::NodeStatusMonitor
Definition: node_status_monitor.hpp:22
uavcan::NodeStatusMonitor::NodeStatus::mode
uint8_t mode
Definition: node_status_monitor.hpp:28
ENFORCE
#define ENFORCE(x)
Definition: platform_specific_components/linux/libuavcan/apps/debug.hpp:13
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
node_status_monitor.hpp
uavcan_linux.hpp
CLIColor::Red
@ Red
debug.hpp
uavcan_linux::TimerPtr
std::shared_ptr< uavcan::Timer > TimerPtr
Definition: platform_specific_components/linux/libuavcan/include/uavcan_linux/helpers.hpp:147
CLIColor::Green
@ Green
CLIColor::Default
@ Default
CLIColor::Blue
@ Blue
uavcan::NodeStatusMonitor::isNodeKnown
bool isNodeKnown(NodeID node_id) const
Definition: node_status_monitor.hpp:262
Monitor::redraw
void redraw(const uavcan::TimerEvent &)
Definition: uavcan_monitor.cpp:113
Monitor::healthToColoredString
static std::pair< CLIColor, std::string > healthToColoredString(const std::uint8_t health)
Definition: uavcan_monitor.cpp:49
Monitor::timer_
uavcan_linux::TimerPtr timer_
Definition: uavcan_monitor.cpp:41
uavcan::NodeStatusMonitor::getNodeStatus
NodeStatus getNodeStatus(NodeID node_id) const
Definition: node_status_monitor.hpp:239
Monitor::Monitor
Monitor(uavcan_linux::NodePtr node)
Definition: uavcan_monitor.cpp:130
CLIColorizer::CLIColorizer
CLIColorizer(CLIColor c)
Definition: uavcan_monitor.cpp:28
Monitor::printStatusLine
void printStatusLine(const uavcan::NodeID nid, const uavcan::NodeStatusMonitor::NodeStatus &status)
Definition: uavcan_monitor.cpp:88
Monitor::modeToColoredString
static std::pair< CLIColor, std::string > modeToColoredString(const std::uint8_t mode)
Definition: uavcan_monitor.cpp:68
std
uavcan_linux::NodePtr
std::shared_ptr< Node > NodePtr
Definition: platform_specific_components/linux/libuavcan/include/uavcan_linux/helpers.hpp:354
uavcan::NodeStatusMonitor::NodeStatusMonitor
NodeStatusMonitor(INode &node)
Definition: node_status_monitor.hpp:184
uavcan::NodeID::Max
static const uint8_t Max
Definition: transfer.hpp:120
uavcan::DurationBase< MonotonicDuration >::getInfinite
static MonotonicDuration getInfinite()
Definition: time.hpp:33
pyuavcan_v0.introspect.node
node
Definition: introspect.py:398
Monitor
Definition: uavcan_monitor.cpp:39
uavcan
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:204
uavcan::ReceivedDataStructure::getSrcNodeID
NodeID getSrcNodeID() const
Definition: generic_subscriber.hpp:75
CLIColor::Cyan
@ Cyan
uavcan_linux::makeNode
static NodePtr makeNode(const std::vector< std::string > &iface_names, ClockAdjustmentMode clock_adjustment_mode=SystemClock::detectPreferredClockAdjustmentMode())
Definition: platform_specific_components/linux/libuavcan/include/uavcan_linux/helpers.hpp:363
uavcan::NodeStatusMonitor::NodeStatus::health
uint8_t health
Definition: node_status_monitor.hpp:27
initNodeInPassiveMode
static uavcan_linux::NodePtr initNodeInPassiveMode(const std::vector< std::string > &ifaces, const std::string &node_name)
Definition: uavcan_monitor.cpp:138
uavcan::TimerEvent
Definition: timer.hpp:32
runForever
static void runForever(const uavcan_linux::NodePtr &node)
Definition: uavcan_monitor.cpp:146
uavcan::NodeStatusMonitor::start
int start()
Definition: node_status_monitor.hpp:196


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:03