Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: UAVCAN UAVCAN_Subscriber
libuavcan_drivers/linux/apps/uavcan_nodetool.cpp@0:dfe6edabb8ec, 2018-04-14 (annotated)
- Committer:
- RuslanUrya
- Date:
- Sat Apr 14 10:25:32 2018 +0000
- Revision:
- 0:dfe6edabb8ec
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
RuslanUrya | 0:dfe6edabb8ec | 1 | /* |
RuslanUrya | 0:dfe6edabb8ec | 2 | * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com> |
RuslanUrya | 0:dfe6edabb8ec | 3 | */ |
RuslanUrya | 0:dfe6edabb8ec | 4 | |
RuslanUrya | 0:dfe6edabb8ec | 5 | #include <iostream> |
RuslanUrya | 0:dfe6edabb8ec | 6 | #include <iomanip> |
RuslanUrya | 0:dfe6edabb8ec | 7 | #include <thread> |
RuslanUrya | 0:dfe6edabb8ec | 8 | #include <mutex> |
RuslanUrya | 0:dfe6edabb8ec | 9 | #include <map> |
RuslanUrya | 0:dfe6edabb8ec | 10 | #include <algorithm> |
RuslanUrya | 0:dfe6edabb8ec | 11 | #include <iterator> |
RuslanUrya | 0:dfe6edabb8ec | 12 | #include <uavcan_linux/uavcan_linux.hpp> |
RuslanUrya | 0:dfe6edabb8ec | 13 | #include <uavcan/protocol/node_status_monitor.hpp> |
RuslanUrya | 0:dfe6edabb8ec | 14 | #include "debug.hpp" |
RuslanUrya | 0:dfe6edabb8ec | 15 | |
RuslanUrya | 0:dfe6edabb8ec | 16 | #include <uavcan/protocol/param/GetSet.hpp> |
RuslanUrya | 0:dfe6edabb8ec | 17 | #include <uavcan/protocol/param/ExecuteOpcode.hpp> |
RuslanUrya | 0:dfe6edabb8ec | 18 | #include <uavcan/equipment/hardpoint/Command.hpp> |
RuslanUrya | 0:dfe6edabb8ec | 19 | |
RuslanUrya | 0:dfe6edabb8ec | 20 | namespace |
RuslanUrya | 0:dfe6edabb8ec | 21 | { |
RuslanUrya | 0:dfe6edabb8ec | 22 | |
RuslanUrya | 0:dfe6edabb8ec | 23 | class StdinLineReader |
RuslanUrya | 0:dfe6edabb8ec | 24 | { |
RuslanUrya | 0:dfe6edabb8ec | 25 | mutable std::mutex mutex_; |
RuslanUrya | 0:dfe6edabb8ec | 26 | std::thread thread_; |
RuslanUrya | 0:dfe6edabb8ec | 27 | std::queue<std::string> queue_; |
RuslanUrya | 0:dfe6edabb8ec | 28 | |
RuslanUrya | 0:dfe6edabb8ec | 29 | void worker() |
RuslanUrya | 0:dfe6edabb8ec | 30 | { |
RuslanUrya | 0:dfe6edabb8ec | 31 | while (true) |
RuslanUrya | 0:dfe6edabb8ec | 32 | { |
RuslanUrya | 0:dfe6edabb8ec | 33 | std::string input; |
RuslanUrya | 0:dfe6edabb8ec | 34 | std::getline(std::cin, input); |
RuslanUrya | 0:dfe6edabb8ec | 35 | std::lock_guard<std::mutex> lock(mutex_); |
RuslanUrya | 0:dfe6edabb8ec | 36 | queue_.push(input); |
RuslanUrya | 0:dfe6edabb8ec | 37 | } |
RuslanUrya | 0:dfe6edabb8ec | 38 | } |
RuslanUrya | 0:dfe6edabb8ec | 39 | |
RuslanUrya | 0:dfe6edabb8ec | 40 | public: |
RuslanUrya | 0:dfe6edabb8ec | 41 | StdinLineReader() |
RuslanUrya | 0:dfe6edabb8ec | 42 | : thread_(&StdinLineReader::worker, this) |
RuslanUrya | 0:dfe6edabb8ec | 43 | { |
RuslanUrya | 0:dfe6edabb8ec | 44 | thread_.detach(); |
RuslanUrya | 0:dfe6edabb8ec | 45 | } |
RuslanUrya | 0:dfe6edabb8ec | 46 | |
RuslanUrya | 0:dfe6edabb8ec | 47 | bool hasPendingInput() const |
RuslanUrya | 0:dfe6edabb8ec | 48 | { |
RuslanUrya | 0:dfe6edabb8ec | 49 | std::lock_guard<std::mutex> lock(mutex_); |
RuslanUrya | 0:dfe6edabb8ec | 50 | return !queue_.empty(); |
RuslanUrya | 0:dfe6edabb8ec | 51 | } |
RuslanUrya | 0:dfe6edabb8ec | 52 | |
RuslanUrya | 0:dfe6edabb8ec | 53 | std::string getLine() |
RuslanUrya | 0:dfe6edabb8ec | 54 | { |
RuslanUrya | 0:dfe6edabb8ec | 55 | std::lock_guard<std::mutex> lock(mutex_); |
RuslanUrya | 0:dfe6edabb8ec | 56 | if (queue_.empty()) |
RuslanUrya | 0:dfe6edabb8ec | 57 | { |
RuslanUrya | 0:dfe6edabb8ec | 58 | throw std::runtime_error("Input queue is empty"); |
RuslanUrya | 0:dfe6edabb8ec | 59 | } |
RuslanUrya | 0:dfe6edabb8ec | 60 | auto ret = queue_.front(); |
RuslanUrya | 0:dfe6edabb8ec | 61 | queue_.pop(); |
RuslanUrya | 0:dfe6edabb8ec | 62 | return ret; |
RuslanUrya | 0:dfe6edabb8ec | 63 | } |
RuslanUrya | 0:dfe6edabb8ec | 64 | |
RuslanUrya | 0:dfe6edabb8ec | 65 | std::vector<std::string> getSplitLine() |
RuslanUrya | 0:dfe6edabb8ec | 66 | { |
RuslanUrya | 0:dfe6edabb8ec | 67 | std::istringstream iss(getLine()); |
RuslanUrya | 0:dfe6edabb8ec | 68 | std::vector<std::string> out; |
RuslanUrya | 0:dfe6edabb8ec | 69 | std::copy(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(), |
RuslanUrya | 0:dfe6edabb8ec | 70 | std::back_inserter(out)); |
RuslanUrya | 0:dfe6edabb8ec | 71 | return out; |
RuslanUrya | 0:dfe6edabb8ec | 72 | } |
RuslanUrya | 0:dfe6edabb8ec | 73 | }; |
RuslanUrya | 0:dfe6edabb8ec | 74 | |
RuslanUrya | 0:dfe6edabb8ec | 75 | uavcan_linux::NodePtr initNode(const std::vector<std::string>& ifaces, uavcan::NodeID nid, const std::string& name) |
RuslanUrya | 0:dfe6edabb8ec | 76 | { |
RuslanUrya | 0:dfe6edabb8ec | 77 | auto node = uavcan_linux::makeNode(ifaces, name.c_str(), |
RuslanUrya | 0:dfe6edabb8ec | 78 | uavcan::protocol::SoftwareVersion(), uavcan::protocol::HardwareVersion(), |
RuslanUrya | 0:dfe6edabb8ec | 79 | nid); |
RuslanUrya | 0:dfe6edabb8ec | 80 | node->setModeOperational(); |
RuslanUrya | 0:dfe6edabb8ec | 81 | return node; |
RuslanUrya | 0:dfe6edabb8ec | 82 | } |
RuslanUrya | 0:dfe6edabb8ec | 83 | |
RuslanUrya | 0:dfe6edabb8ec | 84 | template <typename DataType> |
RuslanUrya | 0:dfe6edabb8ec | 85 | typename DataType::Response call(uavcan_linux::BlockingServiceClient<DataType>& client, |
RuslanUrya | 0:dfe6edabb8ec | 86 | uavcan::NodeID server_node_id, const typename DataType::Request& request) |
RuslanUrya | 0:dfe6edabb8ec | 87 | { |
RuslanUrya | 0:dfe6edabb8ec | 88 | const int res = client.blockingCall(server_node_id, request, uavcan::MonotonicDuration::fromMSec(100)); |
RuslanUrya | 0:dfe6edabb8ec | 89 | ENFORCE(res >= 0); |
RuslanUrya | 0:dfe6edabb8ec | 90 | ENFORCE(client.wasSuccessful()); |
RuslanUrya | 0:dfe6edabb8ec | 91 | return client.getResponse(); |
RuslanUrya | 0:dfe6edabb8ec | 92 | } |
RuslanUrya | 0:dfe6edabb8ec | 93 | |
RuslanUrya | 0:dfe6edabb8ec | 94 | /* |
RuslanUrya | 0:dfe6edabb8ec | 95 | * Command table. |
RuslanUrya | 0:dfe6edabb8ec | 96 | * The structure is: |
RuslanUrya | 0:dfe6edabb8ec | 97 | * command_name : (command_usage_info, command_entry_point) |
RuslanUrya | 0:dfe6edabb8ec | 98 | * This code was written while listening to some bad dubstep so I'm not sure about its quality. |
RuslanUrya | 0:dfe6edabb8ec | 99 | */ |
RuslanUrya | 0:dfe6edabb8ec | 100 | const std::map<std::string, |
RuslanUrya | 0:dfe6edabb8ec | 101 | std::pair<std::string, |
RuslanUrya | 0:dfe6edabb8ec | 102 | std::function<void(const uavcan_linux::NodePtr&, const uavcan::NodeID, |
RuslanUrya | 0:dfe6edabb8ec | 103 | const std::vector<std::string>&)> |
RuslanUrya | 0:dfe6edabb8ec | 104 | > |
RuslanUrya | 0:dfe6edabb8ec | 105 | > commands = |
RuslanUrya | 0:dfe6edabb8ec | 106 | { |
RuslanUrya | 0:dfe6edabb8ec | 107 | { |
RuslanUrya | 0:dfe6edabb8ec | 108 | "param", |
RuslanUrya | 0:dfe6edabb8ec | 109 | { |
RuslanUrya | 0:dfe6edabb8ec | 110 | "No arguments supplied - requests all params from a remote node\n" |
RuslanUrya | 0:dfe6edabb8ec | 111 | "<param_name> <param_value> - assigns parameter <param_name> to value <param_value>", |
RuslanUrya | 0:dfe6edabb8ec | 112 | [](const uavcan_linux::NodePtr& node, const uavcan::NodeID node_id, const std::vector<std::string>& args) |
RuslanUrya | 0:dfe6edabb8ec | 113 | { |
RuslanUrya | 0:dfe6edabb8ec | 114 | auto client = node->makeBlockingServiceClient<uavcan::protocol::param::GetSet>(); |
RuslanUrya | 0:dfe6edabb8ec | 115 | uavcan::protocol::param::GetSet::Request request; |
RuslanUrya | 0:dfe6edabb8ec | 116 | if (args.empty()) |
RuslanUrya | 0:dfe6edabb8ec | 117 | { |
RuslanUrya | 0:dfe6edabb8ec | 118 | while (true) |
RuslanUrya | 0:dfe6edabb8ec | 119 | { |
RuslanUrya | 0:dfe6edabb8ec | 120 | auto response = call(*client, node_id, request); |
RuslanUrya | 0:dfe6edabb8ec | 121 | if (response.name.empty()) |
RuslanUrya | 0:dfe6edabb8ec | 122 | { |
RuslanUrya | 0:dfe6edabb8ec | 123 | break; |
RuslanUrya | 0:dfe6edabb8ec | 124 | } |
RuslanUrya | 0:dfe6edabb8ec | 125 | std::cout |
RuslanUrya | 0:dfe6edabb8ec | 126 | << response |
RuslanUrya | 0:dfe6edabb8ec | 127 | << "\n" << std::string(80, '-') |
RuslanUrya | 0:dfe6edabb8ec | 128 | << std::endl; |
RuslanUrya | 0:dfe6edabb8ec | 129 | request.index++; |
RuslanUrya | 0:dfe6edabb8ec | 130 | } |
RuslanUrya | 0:dfe6edabb8ec | 131 | } |
RuslanUrya | 0:dfe6edabb8ec | 132 | else |
RuslanUrya | 0:dfe6edabb8ec | 133 | { |
RuslanUrya | 0:dfe6edabb8ec | 134 | request.name = args.at(0).c_str(); |
RuslanUrya | 0:dfe6edabb8ec | 135 | // TODO: add support for string parameters |
RuslanUrya | 0:dfe6edabb8ec | 136 | request.value.to<uavcan::protocol::param::Value::Tag::real_value>() = std::stof(args.at(1)); |
RuslanUrya | 0:dfe6edabb8ec | 137 | std::cout << call(*client, node_id, request) << std::endl; |
RuslanUrya | 0:dfe6edabb8ec | 138 | } |
RuslanUrya | 0:dfe6edabb8ec | 139 | } |
RuslanUrya | 0:dfe6edabb8ec | 140 | } |
RuslanUrya | 0:dfe6edabb8ec | 141 | }, |
RuslanUrya | 0:dfe6edabb8ec | 142 | { |
RuslanUrya | 0:dfe6edabb8ec | 143 | "param_save", |
RuslanUrya | 0:dfe6edabb8ec | 144 | { |
RuslanUrya | 0:dfe6edabb8ec | 145 | "Calls uavcan.protocol.param.ExecuteOpcode on a remote node with OPCODE_SAVE", |
RuslanUrya | 0:dfe6edabb8ec | 146 | [](const uavcan_linux::NodePtr& node, const uavcan::NodeID node_id, const std::vector<std::string>&) |
RuslanUrya | 0:dfe6edabb8ec | 147 | { |
RuslanUrya | 0:dfe6edabb8ec | 148 | auto client = node->makeBlockingServiceClient<uavcan::protocol::param::ExecuteOpcode>(); |
RuslanUrya | 0:dfe6edabb8ec | 149 | uavcan::protocol::param::ExecuteOpcode::Request request; |
RuslanUrya | 0:dfe6edabb8ec | 150 | request.opcode = request.OPCODE_SAVE; |
RuslanUrya | 0:dfe6edabb8ec | 151 | std::cout << call(*client, node_id, request) << std::endl; |
RuslanUrya | 0:dfe6edabb8ec | 152 | } |
RuslanUrya | 0:dfe6edabb8ec | 153 | } |
RuslanUrya | 0:dfe6edabb8ec | 154 | }, |
RuslanUrya | 0:dfe6edabb8ec | 155 | { |
RuslanUrya | 0:dfe6edabb8ec | 156 | "param_erase", |
RuslanUrya | 0:dfe6edabb8ec | 157 | { |
RuslanUrya | 0:dfe6edabb8ec | 158 | "Calls uavcan.protocol.param.ExecuteOpcode on a remote node with OPCODE_ERASE", |
RuslanUrya | 0:dfe6edabb8ec | 159 | [](const uavcan_linux::NodePtr& node, const uavcan::NodeID node_id, const std::vector<std::string>&) |
RuslanUrya | 0:dfe6edabb8ec | 160 | { |
RuslanUrya | 0:dfe6edabb8ec | 161 | auto client = node->makeBlockingServiceClient<uavcan::protocol::param::ExecuteOpcode>(); |
RuslanUrya | 0:dfe6edabb8ec | 162 | uavcan::protocol::param::ExecuteOpcode::Request request; |
RuslanUrya | 0:dfe6edabb8ec | 163 | request.opcode = request.OPCODE_ERASE; |
RuslanUrya | 0:dfe6edabb8ec | 164 | std::cout << call(*client, node_id, request) << std::endl; |
RuslanUrya | 0:dfe6edabb8ec | 165 | } |
RuslanUrya | 0:dfe6edabb8ec | 166 | } |
RuslanUrya | 0:dfe6edabb8ec | 167 | }, |
RuslanUrya | 0:dfe6edabb8ec | 168 | { |
RuslanUrya | 0:dfe6edabb8ec | 169 | "restart", |
RuslanUrya | 0:dfe6edabb8ec | 170 | { |
RuslanUrya | 0:dfe6edabb8ec | 171 | "Restarts a remote node using uavcan.protocol.RestartNode", |
RuslanUrya | 0:dfe6edabb8ec | 172 | [](const uavcan_linux::NodePtr& node, const uavcan::NodeID node_id, const std::vector<std::string>&) |
RuslanUrya | 0:dfe6edabb8ec | 173 | { |
RuslanUrya | 0:dfe6edabb8ec | 174 | auto client = node->makeBlockingServiceClient<uavcan::protocol::RestartNode>(); |
RuslanUrya | 0:dfe6edabb8ec | 175 | uavcan::protocol::RestartNode::Request request; |
RuslanUrya | 0:dfe6edabb8ec | 176 | request.magic_number = request.MAGIC_NUMBER; |
RuslanUrya | 0:dfe6edabb8ec | 177 | (void)client->blockingCall(node_id, request); |
RuslanUrya | 0:dfe6edabb8ec | 178 | if (client->wasSuccessful()) |
RuslanUrya | 0:dfe6edabb8ec | 179 | { |
RuslanUrya | 0:dfe6edabb8ec | 180 | std::cout << client->getResponse() << std::endl; |
RuslanUrya | 0:dfe6edabb8ec | 181 | } |
RuslanUrya | 0:dfe6edabb8ec | 182 | else |
RuslanUrya | 0:dfe6edabb8ec | 183 | { |
RuslanUrya | 0:dfe6edabb8ec | 184 | std::cout << "<NO RESPONSE>" << std::endl; |
RuslanUrya | 0:dfe6edabb8ec | 185 | } |
RuslanUrya | 0:dfe6edabb8ec | 186 | } |
RuslanUrya | 0:dfe6edabb8ec | 187 | } |
RuslanUrya | 0:dfe6edabb8ec | 188 | }, |
RuslanUrya | 0:dfe6edabb8ec | 189 | { |
RuslanUrya | 0:dfe6edabb8ec | 190 | "info", |
RuslanUrya | 0:dfe6edabb8ec | 191 | { |
RuslanUrya | 0:dfe6edabb8ec | 192 | "Calls uavcan.protocol.GetNodeInfo on a remote node", |
RuslanUrya | 0:dfe6edabb8ec | 193 | [](const uavcan_linux::NodePtr& node, const uavcan::NodeID node_id, const std::vector<std::string>&) |
RuslanUrya | 0:dfe6edabb8ec | 194 | { |
RuslanUrya | 0:dfe6edabb8ec | 195 | auto client = node->makeBlockingServiceClient<uavcan::protocol::GetNodeInfo>(); |
RuslanUrya | 0:dfe6edabb8ec | 196 | std::cout << call(*client, node_id, uavcan::protocol::GetNodeInfo::Request()) << std::endl; |
RuslanUrya | 0:dfe6edabb8ec | 197 | } |
RuslanUrya | 0:dfe6edabb8ec | 198 | } |
RuslanUrya | 0:dfe6edabb8ec | 199 | }, |
RuslanUrya | 0:dfe6edabb8ec | 200 | { |
RuslanUrya | 0:dfe6edabb8ec | 201 | "transport_stats", |
RuslanUrya | 0:dfe6edabb8ec | 202 | { |
RuslanUrya | 0:dfe6edabb8ec | 203 | "Calls uavcan.protocol.GetTransportStats on a remote node", |
RuslanUrya | 0:dfe6edabb8ec | 204 | [](const uavcan_linux::NodePtr& node, const uavcan::NodeID node_id, const std::vector<std::string>&) |
RuslanUrya | 0:dfe6edabb8ec | 205 | { |
RuslanUrya | 0:dfe6edabb8ec | 206 | auto client = node->makeBlockingServiceClient<uavcan::protocol::GetTransportStats>(); |
RuslanUrya | 0:dfe6edabb8ec | 207 | std::cout << call(*client, node_id, uavcan::protocol::GetTransportStats::Request()) << std::endl; |
RuslanUrya | 0:dfe6edabb8ec | 208 | } |
RuslanUrya | 0:dfe6edabb8ec | 209 | } |
RuslanUrya | 0:dfe6edabb8ec | 210 | }, |
RuslanUrya | 0:dfe6edabb8ec | 211 | { |
RuslanUrya | 0:dfe6edabb8ec | 212 | "hardpoint", |
RuslanUrya | 0:dfe6edabb8ec | 213 | { |
RuslanUrya | 0:dfe6edabb8ec | 214 | "Publishes uavcan.equipment.hardpoint.Command\n" |
RuslanUrya | 0:dfe6edabb8ec | 215 | "Expected argument: command", |
RuslanUrya | 0:dfe6edabb8ec | 216 | [](const uavcan_linux::NodePtr& node, const uavcan::NodeID, const std::vector<std::string>& args) |
RuslanUrya | 0:dfe6edabb8ec | 217 | { |
RuslanUrya | 0:dfe6edabb8ec | 218 | uavcan::equipment::hardpoint::Command msg; |
RuslanUrya | 0:dfe6edabb8ec | 219 | msg.command = std::stoi(args.at(0)); |
RuslanUrya | 0:dfe6edabb8ec | 220 | auto pub = node->makePublisher<uavcan::equipment::hardpoint::Command>(); |
RuslanUrya | 0:dfe6edabb8ec | 221 | (void)pub->broadcast(msg); |
RuslanUrya | 0:dfe6edabb8ec | 222 | } |
RuslanUrya | 0:dfe6edabb8ec | 223 | } |
RuslanUrya | 0:dfe6edabb8ec | 224 | } |
RuslanUrya | 0:dfe6edabb8ec | 225 | }; |
RuslanUrya | 0:dfe6edabb8ec | 226 | |
RuslanUrya | 0:dfe6edabb8ec | 227 | void runForever(const uavcan_linux::NodePtr& node) |
RuslanUrya | 0:dfe6edabb8ec | 228 | { |
RuslanUrya | 0:dfe6edabb8ec | 229 | StdinLineReader stdin_reader; |
RuslanUrya | 0:dfe6edabb8ec | 230 | std::cout << "> " << std::flush; |
RuslanUrya | 0:dfe6edabb8ec | 231 | while (true) |
RuslanUrya | 0:dfe6edabb8ec | 232 | { |
RuslanUrya | 0:dfe6edabb8ec | 233 | ENFORCE(node->spin(uavcan::MonotonicDuration::fromMSec(10)) >= 0); |
RuslanUrya | 0:dfe6edabb8ec | 234 | if (!stdin_reader.hasPendingInput()) |
RuslanUrya | 0:dfe6edabb8ec | 235 | { |
RuslanUrya | 0:dfe6edabb8ec | 236 | continue; |
RuslanUrya | 0:dfe6edabb8ec | 237 | } |
RuslanUrya | 0:dfe6edabb8ec | 238 | const auto words = stdin_reader.getSplitLine(); |
RuslanUrya | 0:dfe6edabb8ec | 239 | bool command_is_known = false; |
RuslanUrya | 0:dfe6edabb8ec | 240 | |
RuslanUrya | 0:dfe6edabb8ec | 241 | try |
RuslanUrya | 0:dfe6edabb8ec | 242 | { |
RuslanUrya | 0:dfe6edabb8ec | 243 | if (words.size() >= 2) |
RuslanUrya | 0:dfe6edabb8ec | 244 | { |
RuslanUrya | 0:dfe6edabb8ec | 245 | const auto cmd = words.at(0); |
RuslanUrya | 0:dfe6edabb8ec | 246 | const uavcan::NodeID node_id(std::stoi(words.at(1))); |
RuslanUrya | 0:dfe6edabb8ec | 247 | auto it = commands.find(cmd); |
RuslanUrya | 0:dfe6edabb8ec | 248 | if (it != std::end(commands)) |
RuslanUrya | 0:dfe6edabb8ec | 249 | { |
RuslanUrya | 0:dfe6edabb8ec | 250 | command_is_known = true; |
RuslanUrya | 0:dfe6edabb8ec | 251 | it->second.second(node, node_id, std::vector<std::string>(words.begin() + 2, words.end())); |
RuslanUrya | 0:dfe6edabb8ec | 252 | } |
RuslanUrya | 0:dfe6edabb8ec | 253 | } |
RuslanUrya | 0:dfe6edabb8ec | 254 | } |
RuslanUrya | 0:dfe6edabb8ec | 255 | catch (std::exception& ex) |
RuslanUrya | 0:dfe6edabb8ec | 256 | { |
RuslanUrya | 0:dfe6edabb8ec | 257 | std::cout << "FAILURE\n" << ex.what() << std::endl; |
RuslanUrya | 0:dfe6edabb8ec | 258 | } |
RuslanUrya | 0:dfe6edabb8ec | 259 | |
RuslanUrya | 0:dfe6edabb8ec | 260 | if (!command_is_known) |
RuslanUrya | 0:dfe6edabb8ec | 261 | { |
RuslanUrya | 0:dfe6edabb8ec | 262 | std::cout << "<command> <remote node id> [args...]\n"; |
RuslanUrya | 0:dfe6edabb8ec | 263 | std::cout << "Say 'help' to get help.\n"; // I'll show myself out. |
RuslanUrya | 0:dfe6edabb8ec | 264 | |
RuslanUrya | 0:dfe6edabb8ec | 265 | if (!words.empty() && words.at(0) == "help") |
RuslanUrya | 0:dfe6edabb8ec | 266 | { |
RuslanUrya | 0:dfe6edabb8ec | 267 | std::cout << "Usage:\n\n"; |
RuslanUrya | 0:dfe6edabb8ec | 268 | for (auto& cmd : commands) |
RuslanUrya | 0:dfe6edabb8ec | 269 | { |
RuslanUrya | 0:dfe6edabb8ec | 270 | std::cout << cmd.first << "\n" << cmd.second.first << "\n\n"; |
RuslanUrya | 0:dfe6edabb8ec | 271 | } |
RuslanUrya | 0:dfe6edabb8ec | 272 | } |
RuslanUrya | 0:dfe6edabb8ec | 273 | } |
RuslanUrya | 0:dfe6edabb8ec | 274 | std::cout << "> " << std::flush; |
RuslanUrya | 0:dfe6edabb8ec | 275 | } |
RuslanUrya | 0:dfe6edabb8ec | 276 | } |
RuslanUrya | 0:dfe6edabb8ec | 277 | |
RuslanUrya | 0:dfe6edabb8ec | 278 | } |
RuslanUrya | 0:dfe6edabb8ec | 279 | |
RuslanUrya | 0:dfe6edabb8ec | 280 | int main(int argc, const char** argv) |
RuslanUrya | 0:dfe6edabb8ec | 281 | { |
RuslanUrya | 0:dfe6edabb8ec | 282 | try |
RuslanUrya | 0:dfe6edabb8ec | 283 | { |
RuslanUrya | 0:dfe6edabb8ec | 284 | if (argc < 3) |
RuslanUrya | 0:dfe6edabb8ec | 285 | { |
RuslanUrya | 0:dfe6edabb8ec | 286 | std::cerr << "Usage:\n\t" << argv[0] << " <node-id> <can-iface-name-1> [can-iface-name-N...]" << std::endl; |
RuslanUrya | 0:dfe6edabb8ec | 287 | return 1; |
RuslanUrya | 0:dfe6edabb8ec | 288 | } |
RuslanUrya | 0:dfe6edabb8ec | 289 | const int self_node_id = std::stoi(argv[1]); |
RuslanUrya | 0:dfe6edabb8ec | 290 | const std::vector<std::string> iface_names(argv + 2, argv + argc); |
RuslanUrya | 0:dfe6edabb8ec | 291 | uavcan_linux::NodePtr node = initNode(iface_names, self_node_id, "org.uavcan.linux_app.nodetool"); |
RuslanUrya | 0:dfe6edabb8ec | 292 | runForever(node); |
RuslanUrya | 0:dfe6edabb8ec | 293 | return 0; |
RuslanUrya | 0:dfe6edabb8ec | 294 | } |
RuslanUrya | 0:dfe6edabb8ec | 295 | catch (const std::exception& ex) |
RuslanUrya | 0:dfe6edabb8ec | 296 | { |
RuslanUrya | 0:dfe6edabb8ec | 297 | std::cerr << "Error: " << ex.what() << std::endl; |
RuslanUrya | 0:dfe6edabb8ec | 298 | return 1; |
RuslanUrya | 0:dfe6edabb8ec | 299 | } |
RuslanUrya | 0:dfe6edabb8ec | 300 | } |