Network Nodes missing Axes?

I’m having intermittent problems trying to start the network from my C++ application.

The underlying symptom is that it transitions to operational, but none of the drive nodes show that they have any axes.

There are no network log messages at this point.

Here’s a brief snippet from my log.

[EtherCAT] [FSM] Starting RTOS. 
[EtherCAT] [FSM] RTOS is running. 
[EtherCAT] Using RMP runtime from: "c:/path/to/app/RSI" 
[EtherCAT] [FSM] Attempting (try #1) to start the EtherCAT network...
[EtherCAT] Starting EtherCAT network...
[EtherCAT]   [StartAttemptBegin] Network State: (256): UNINITIALIZED
[EtherCAT]   Network State: (256): UNINITIALIZED
[EtherCAT]   NetworkStart() took 19.235 seconds.
[EtherCAT]   Network State: (260): OPERATIONAL
[EtherCAT] RMP Initialization State: OK
[EtherCAT] EtherCAT network started successfully.
[EtherCAT]   [StartAttemptEnd] Network State: (260): OPERATIONAL
[EtherCAT] [FSM] EtherCAT network start attempt complete.
[EtherCAT] RMP MPI Version: 04.04.02.RMP 
[EtherCAT] RMP MPI Version: 918 
[EtherCAT] Rapid Code Version: 8.3.1 
[EtherCAT] Axis License Count64 
[EtherCAT] Network Nodes: 6 
[EtherCAT]   Input Nodes: 62 
[EtherCAT]   Output Nodes: 32 
[EtherCAT]   Axis Nodes: 0 

What could I do that would result in this state?

I don’t see this happening when the network is already started before my application runs. (My app doesn’t attempt to start the network in that case.)

I’m using RTOS::RTOSGet()::INtimeStart() to start INtime, waiting until RTOS::RTOSGet()::INtimeStatusGet() returns INtimeStatusOK before proceeding.

I load the RTA with MotionController::CreateFromSoftware(const_cast<char*>((rsi_dir.string() + "/").c_str())) and do some initial configuration (interrupts, e.g.).

Then I call NetworkStart(r::RSINetworkStartModeOPERATIONAL,r::RSINetworkStartupMethodNORMAL,network_start_timeout_sec*1000);

After checking the network state to ensure thath it’s operational, I proceed to query for some basic info (listed above).

I don’t see this behavior if I do everything in RapidSetup.

Before starting the network, I don’t make any attempt to stop recorders do any reconfiguration. I occasionally see error messages that might be related.

So, invoking MotionController::Refresh() after I start the network seems to resolve the behavior.

My next question is, why should I need to do that if it always ought to be done? Why wouldn’t the API implementation be a better place for it?

I’m glad it’s working for youw now.

If your application was starting and stopping the network (without expecting AxisCount to change), we wouldn’t want to Refresh() since it would invalidate the existing Axis objects.

So, should I only refresh if I expect the axis count to change? Other than axis_count:0, how would I know that it had changed if the network’s not operational? And wouldn’t restarting the network invalidate all the objects anyway?

Since yours in in the startup of your app, the refresh should always be fine.

Stopping then restarting the network does not invalidate objects, assuming the network topology remains unchanged.

It doesn’t invalidate axis objects?

What happens to threads that are waiting for interrupts (on, say, axis objects) if you refresh?

Starting and stopping the network does not invalidate Axis objects, so long as the topology stays the same.

Refresh() will invalidate the Axis objects and they won’t be notified of interrupts.