#include <iomanip>
#include <iostream>
#include <map>
#include <sstream>
#include <vector>
#include "SampleAppsHelper.h"
#include "rsi.h"
static const std::map<RSINetworkType, std::string> RSINetworkTypeMap = {
};
static const std::map<RSINetworkState, std::string> RSINetworkStateMap = {
};
struct MdpConstants
{
static constexpr int DEVICE_TYPE_INDEX = 0x1000;
static constexpr int DEVICE_TYPE_SUB_INDEX = 0;
static constexpr int DEVICE_TYPE_BYTE_SIZE = 4;
};
static std::vector<RapidCodeNetworkNode *> GetNodeList(
MotionController *controller)
{
std::vector<RapidCodeNetworkNode *> nodes;
for (int i = 0; i < controller->NetworkNodeCountGet(); ++i)
{
RapidCodeNetworkNode *node = controller->NetworkNodeGet(i);
if (node == nullptr)
{
throw std::runtime_error("Error creating the network node, it is null.");
}
if (!node->Exists())
{
throw std::runtime_error("The network node should exist after we get it.");
}
nodes.push_back(node);
}
return nodes;
}
static std::string GetDeviceType(RapidCodeNetworkNode *node)
{
std::string deviceType = "";
try
{
uint32_t deviceTypeValue =
node->ServiceChannelRead(MdpConstants::DEVICE_TYPE_INDEX, MdpConstants::DEVICE_TYPE_SUB_INDEX, MdpConstants::DEVICE_TYPE_BYTE_SIZE);
std::ostringstream deviceTypeStream;
deviceTypeStream << "0x" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << deviceTypeValue;
deviceType = deviceTypeStream.str();
}
catch (std::exception err)
{
deviceType = "Exception trying to read device type";
}
return deviceType;
}
static std::string ReadNodeInfo(RapidCodeNetworkNode *node)
{
std::ostringstream nodeInfo;
nodeInfo << "\n";
nodeInfo << "Node[" << node->NumberGet() << "] - " << node->NameGet() << " ______________________________________________\n";
nodeInfo << " Vendor: " << node->VendorNameGet();
nodeInfo << " Product: " << node->ProductNameGet() << "\n";
nodeInfo << " VendorID: 0x" << std::hex << std::setw(8) << std::setfill('0') << node->VendorIdGet();
nodeInfo << " ProductCode: 0x" << std::setw(8) << node->ProductCodeGet() << "\n";
nodeInfo << " HardwareRev: 0x" << std::setw(8) << node->RevisionGet();
nodeInfo << " SerialNumber: " << node->SerialNumberGet() << "\n";
nodeInfo << " StationAlias: 0x" << std::setw(8) << node->StationAliasGet();
nodeInfo << " AxisCount: " << std::dec << node->AxisCountGet() << "\n";
nodeInfo << " DeviceType: " << GetDeviceType(node);
nodeInfo << " (For Mdp by reading SDO 0x" << std::hex << std::setw(4) << MdpConstants::DEVICE_TYPE_INDEX << ")\n";
nodeInfo << " SegmentCount: " << node->SegmentCountGet() << "\n";
nodeInfo << " DI: " << node->DigitalInCountGet();
nodeInfo << " DO: " << node->DigitalOutCountGet();
nodeInfo << " AI: " << node->AnalogInCountGet();
nodeInfo << " AO: " << node->AnalogOutCountGet() << "\n";
return nodeInfo.str();
}
int main()
{
const std::string SAMPLE_APP_NAME = "Utilities: Print Network Topology";
int exitCode = -1;
try
{
std::vector<RapidCodeNetworkNode *> nodes = GetNodeList(controller);
std::ostringstream topologyInfo;
topologyInfo << "EtherCAT: " << std::to_string(nodes.size());
topologyInfo << " Nodes, " << RSINetworkTypeMap.at(controller->NetworkTypeGet());
topologyInfo << " " << RSINetworkStateMap.at(controller->NetworkStateGet()) << "\n";
for (RapidCodeNetworkNode *node : nodes)
{
topologyInfo << ReadNodeInfo(node);
}
topologyInfo << "\nNetworkInputs count: " << controller->NetworkInputCountGet() << " _________________________________\n";
for (int i = 0; i < controller->NetworkInputCountGet(); ++i)
{
topologyInfo << " [" << i << "] - " << std::setw(70) << controller->NetworkInputNameGet(i);
topologyInfo << " Bits: " << controller->NetworkInputBitSizeGet(i) << "\n";
}
topologyInfo << "NetworkOutputs count: " << controller->NetworkOutputCountGet() << " _________________________________\n";
for (int i = 0; i < controller->NetworkOutputCountGet(); ++i)
{
topologyInfo << " [" << i << "] - " << std::setw(70) << controller->NetworkOutputNameGet(i);
topologyInfo << " Bits: " << controller->NetworkOutputBitSizeGet(i) << "\n";
}
std::cout << topologyInfo.str() << std::endl;
exitCode = 0;
}
catch (const std::exception &ex)
{
std::cerr << ex.what() << std::endl;
exitCode = -1;
}
controller->Delete();
return exitCode;
}
static MotionController * Create(CreationParameters *creationParameters)
Initialize and start the RMP EtherCAT controller.
Represents the RMP soft motion controller. This class provides an interface to general controller con...
@ RSINetworkStatePREOPERATIONAL
EtherCAT preoperational.
@ RSINetworkStateSHUTDOWN
EtherCAT was shutdown or stopped, must restart.
@ RSINetworkStateDISCOVERED
EtherCAT nodes discovered but not started.
@ RSINetworkStateDISCOVERING
EtherCAT network is in the process of discovering nodes.
@ RSINetworkStateERROR
Error.
@ RSINetworkStateOPERATIONAL
EtherCAT operational, good state.
@ RSINetworkStateSTARTING
EtherCAT is starting.
@ RSINetworkStateUNINITIALIZED
EtherCAT not yet started.
@ RSINetworkTypeRING
A Ring topology is a chain of linked Node(s) going from the Controllers Out port to the In port.
@ RSINetworkTypeSTRING
A String topology is chain of linked Node(s) to the Controller from the In or Out port.
@ RSINetworkTypeDUAL_STRING
A Dual String topology is two chained links of Node(s) to the Controller from the In and Out ports.
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.