#include <iomanip>
#include <iostream>
#include <map>
#include <sstream>
#include <vector>
#include "SampleAppsHelper.h"
#include "rsi.h"
static const std::map<RSINetworkType, std::string> RSINetworkTypeMap = {
{RSINetworkType::RSINetworkTypeSTRING, "RSINetworkTypeSTRING"},
{RSINetworkType::RSINetworkTypeDUAL_STRING, "RSINetworkTypeDUAL_STRING"},
{RSINetworkType::RSINetworkTypeRING, "RSINetworkTypeRING"}
};
static const std::map<RSINetworkState, std::string> RSINetworkStateMap = {
{RSINetworkState::RSINetworkStateUNINITIALIZED, "RSINetworkStateUNINITIALIZED"},
{RSINetworkState::RSINetworkStateDISCOVERING, "RSINetworkStateDISCOVERING"},
{RSINetworkState::RSINetworkStateDISCOVERED, "RSINetworkStateDISCOVERED"},
{RSINetworkState::RSINetworkStatePREOPERATIONAL, "RSINetworkStatePREOPERATIONAL"},
{RSINetworkState::RSINetworkStateOPERATIONAL, "RSINetworkStateOPERATIONAL"},
{RSINetworkState::RSINetworkStateERROR, "RSINetworkStateERROR"},
{RSINetworkState::RSINetworkStateSHUTDOWN, "RSINetworkStateSHUTDOWN"},
{RSINetworkState::RSINetworkStateSTARTING, "RSINetworkStateSTARTING"}
};
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;
{
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";
{
}
topologyInfo <<
"NetworkOutputs count: " << controller->
NetworkOutputCountGet() <<
" _________________________________\n";
{
}
std::cout << topologyInfo.str() << std::endl;
exitCode = 0;
}
catch (const std::exception &ex)
{
std::cerr << ex.what() << std::endl;
exitCode = -1;
}
return exitCode;
}
NetworkNode * NetworkNodeGet(int32_t nodeNumber)
NetworkNodeGet returns a pointer to a RapidCodeNetworkNode object using its node number and initializ...
RSINetworkState NetworkStateGet()
int32_t NetworkNodeCountGet()
void Delete(void)
Delete the MotionController and all its objects.
int32_t NetworkOutputCountGet()
Represents the RMP soft motion controller. This class provides an interface to general controller con...
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.