APIs, concepts, guides, and more
PrintNetworkTopology.cpp
1
10#include <iomanip>
11#include <iostream>
12#include <map>
13#include <sstream>
14#include <vector>
15
16#include "SampleAppsHelper.h" // Import our helper functions.
17#include "rsi.h" // Import our RapidCode Library.
18
19using namespace RSI::RapidCode; // Import the RapidCode namespace
20
21// Map of the RSINetworkType enum to string
22static const std::map<RSINetworkType, std::string> RSINetworkTypeMap = {
23 {RSINetworkType::RSINetworkTypeSTRING, "RSINetworkTypeSTRING"},
24 {RSINetworkType::RSINetworkTypeDUAL_STRING, "RSINetworkTypeDUAL_STRING"},
25 {RSINetworkType::RSINetworkTypeRING, "RSINetworkTypeRING"}
26};
27
28// Map of the RSINetworkState enum to string
29static const std::map<RSINetworkState, std::string> RSINetworkStateMap = {
30 {RSINetworkState::RSINetworkStateUNINITIALIZED, "RSINetworkStateUNINITIALIZED"},
31 {RSINetworkState::RSINetworkStateDISCOVERING, "RSINetworkStateDISCOVERING"},
32 {RSINetworkState::RSINetworkStateDISCOVERED, "RSINetworkStateDISCOVERED"},
33 {RSINetworkState::RSINetworkStatePREOPERATIONAL, "RSINetworkStatePREOPERATIONAL"},
34 {RSINetworkState::RSINetworkStateOPERATIONAL, "RSINetworkStateOPERATIONAL"},
35 {RSINetworkState::RSINetworkStateERROR, "RSINetworkStateERROR"},
36 {RSINetworkState::RSINetworkStateSHUTDOWN, "RSINetworkStateSHUTDOWN"},
37 {RSINetworkState::RSINetworkStateSTARTING, "RSINetworkStateSTARTING"}
38};
39
40// Constants for reading the device type from the Mdp
41struct MdpConstants
42{
43 static constexpr int DEVICE_TYPE_INDEX = 0x1000;
44 static constexpr int DEVICE_TYPE_SUB_INDEX = 0;
45 static constexpr int DEVICE_TYPE_BYTE_SIZE = 4;
46};
47
48// Helper function to get the list of network nodes from the controller
49static std::vector<RapidCodeNetworkNode *> GetNodeList(MotionController *controller)
50{
51 std::vector<RapidCodeNetworkNode *> nodes;
52 for (int i = 0; i < controller->NetworkNodeCountGet(); ++i)
53 {
54 RapidCodeNetworkNode *node = controller->NetworkNodeGet(i);
55
56 if (node == nullptr)
57 {
58 throw std::runtime_error("Error creating the network node, it is null.");
59 }
60
61 if (!node->Exists())
62 {
63 throw std::runtime_error("The network node should exist after we get it.");
64 }
65
66 nodes.push_back(node);
67 }
68 return nodes;
69}
70
71// Helper function to get the device type of a node from the Mdp
72static std::string GetDeviceType(RapidCodeNetworkNode *node)
73{
74 std::string deviceType = "";
75 try
76 {
77 uint32_t deviceTypeValue =
78 node->ServiceChannelRead(MdpConstants::DEVICE_TYPE_INDEX, MdpConstants::DEVICE_TYPE_SUB_INDEX, MdpConstants::DEVICE_TYPE_BYTE_SIZE);
79
80 std::ostringstream deviceTypeStream;
81 deviceTypeStream << "0x" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << deviceTypeValue;
82
83 deviceType = deviceTypeStream.str();
84 }
85 catch (std::exception err)
86 {
87 deviceType = "Exception trying to read device type";
88 }
89 return deviceType;
90}
91
92// Helper function to read the information of a node into a string
93static std::string ReadNodeInfo(RapidCodeNetworkNode *node)
94{
95 std::ostringstream nodeInfo;
96
97 nodeInfo << "\n"; // for spacing
98 nodeInfo << "Node[" << node->NumberGet() << "] - " << node->NameGet() << " ______________________________________________\n";
99
100 nodeInfo << " Vendor: " << node->VendorNameGet();
101 nodeInfo << " Product: " << node->ProductNameGet() << "\n";
102
103 nodeInfo << " VendorID: 0x" << std::hex << std::setw(8) << std::setfill('0') << node->VendorIdGet();
104 nodeInfo << " ProductCode: 0x" << std::setw(8) << node->ProductCodeGet() << "\n";
105
106 nodeInfo << " HardwareRev: 0x" << std::setw(8) << node->RevisionGet();
107 nodeInfo << " SerialNumber: " << node->SerialNumberGet() << "\n";
108
109 nodeInfo << " StationAlias: 0x" << std::setw(8) << node->StationAliasGet();
110 nodeInfo << " AxisCount: " << std::dec << node->AxisCountGet() << "\n";
111
112 nodeInfo << " DeviceType: " << GetDeviceType(node);
113 nodeInfo << " (For Mdp by reading SDO 0x" << std::hex << std::setw(4) << MdpConstants::DEVICE_TYPE_INDEX << ")\n";
114
115 nodeInfo << " SegmentCount: " << node->SegmentCountGet() << "\n";
116
117 nodeInfo << " DI: " << node->DigitalInCountGet();
118 nodeInfo << " DO: " << node->DigitalOutCountGet();
119 nodeInfo << " AI: " << node->AnalogInCountGet();
120 nodeInfo << " AO: " << node->AnalogOutCountGet() << "\n";
121
122 return nodeInfo.str();
123}
124
125int main()
126{
127 const std::string SAMPLE_APP_NAME = "Utilities: Print Network Topology";
128
129 // Print a start message to indicate that the sample app has started
130 SampleAppsHelper::PrintHeader(SAMPLE_APP_NAME);
131
132 /* RAPIDCODE INITIALIZATION */
133
134 // Create the controller
136 MotionController *controller = MotionController::Create(&params);
137
138 int exitCode = -1; // Set the exit code to an error value.
139 try // Ensure that the controller is deleted if an error occurs.
140 {
142
143 /* SAMPLE APP BODY */
144
145 // Get the nodes
146 std::vector<RapidCodeNetworkNode *> nodes = GetNodeList(controller);
147
148 // Print the network topology
149 std::ostringstream topologyInfo;
150
151 // Add the overview information
152 topologyInfo << "EtherCAT: " << std::to_string(nodes.size());
153 topologyInfo << " Nodes, " << RSINetworkTypeMap.at(controller->NetworkTypeGet());
154 topologyInfo << " " << RSINetworkStateMap.at(controller->NetworkStateGet()) << "\n";
155
156 // Add information for each node
157 for (RapidCodeNetworkNode *node : nodes)
158 {
159 topologyInfo << ReadNodeInfo(node);
160 }
161
162 // Add network input information
163 topologyInfo << "\nNetworkInputs count: " << controller->NetworkInputCountGet() << " _________________________________\n";
164 for (int i = 0; i < controller->NetworkInputCountGet(); ++i)
165 {
166 topologyInfo << " [" << i << "] - " << std::setw(70) << controller->NetworkInputNameGet(i);
167 topologyInfo << " Bits: " << controller->NetworkInputBitSizeGet(i) << "\n";
168 }
169
170 // Add network output information
171 topologyInfo << "NetworkOutputs count: " << controller->NetworkOutputCountGet() << " _________________________________\n";
172 for (int i = 0; i < controller->NetworkOutputCountGet(); ++i)
173 {
174 topologyInfo << " [" << i << "] - " << std::setw(70) << controller->NetworkOutputNameGet(i);
175 topologyInfo << " Bits: " << controller->NetworkOutputBitSizeGet(i) << "\n";
176 }
177
178 // Print the accumulated string
179 std::cout << topologyInfo.str() << std::endl;
180
181 exitCode = 0;
182 }
183 catch (const std::exception &ex)
184 {
185 std::cerr << ex.what() << std::endl;
186 exitCode = -1;
187 }
188 // Delete the controller as the program exits to ensure memory is deallocated in the correct order
189 controller->Delete();
190
191 // Print a message to indicate the sample app has finished and if it was successful or not
192 SampleAppsHelper::PrintFooter(SAMPLE_APP_NAME, exitCode);
193
194 return exitCode;
195}
NetworkNode * NetworkNodeGet(int32_t nodeNumber)
NetworkNodeGet returns a pointer to a RapidCodeNetworkNode object using its node number and initializ...
RSINetworkState NetworkStateGet()
static MotionController * Create()
Initialize and start the RMP EtherCAT controller.
void Delete(void)
Delete the MotionController and all its objects.
Represents the RMP soft motion controller. This class provides an interface to general controller con...
Definition rsi.h:796
const char *const NetworkOutputNameGet(int32_t index)
Get the name of a PDO output.
int32_t NetworkOutputBitSizeGet(int32_t index)
Get the size (in bits) of a PDO output.
int32_t NetworkInputCountGet()
Get the number of PDO inputs found on the network.
int32_t NetworkInputBitSizeGet(int32_t index)
Get the size (in bits) of a network input.
RSINetworkType NetworkTypeGet()
Returns network type. (Currently only STRING type is supported.)
const char *const NetworkInputNameGet(int32_t index)
Get the name of a PDO network input.
static void PrintFooter(std::string sampleAppName, int exitCode)
Print a message to indicate the sample app has finished and if it was successful or not.
static void CheckErrors(RapidCodeObject *rsiObject)
Checks for errors in the given RapidCodeObject and throws an exception if any non-warning errors are ...
static void PrintHeader(std::string sampleAppName)
Print a start message to indicate that the sample app has started.
static MotionController::CreationParameters GetCreationParameters()
Returns a MotionController::CreationParameters object with user-defined parameters.
CreationParameters for MotionController::Create.
Definition rsi.h:857