Connectivity IO record and replay add-on

This .NET plugin can record values being written to simulation through the Connectivity feature and then replay them into another simulation run without the external connection. It allows easier debugging of issues, non-realtime operations like recording or Blender animation export, and saving warmup sequences or demos with layouts to be used later.

Works with VC 4.4 and probably with VC 4.3. Install by copying the dll to your VC installation folder.
IO record and replay add-on.zip (15.5 KB)
EDIT* Link updated, it should now work with 4.6.

Features:

  • Records input values coming from Connectivity to simulation and can replay them back into the simulation later without the external connection.
  • Replay uses simulation time scheduling so its accuracy doesn’t depend on playback speed or pauses.
  • Inputs to record are automatically imported from active “Server to simulation” variable groups, and can be different for each recording.
  • Multiple recordings can be taken and saved within the .vcmx file.
  • Can record and replay all simulation variable types supported by the Connectivity feature. However, saving recordings with Vector or Matrix values likely won’t work.

For debugging layouts this can also be used together with the Simulation time slider add-on.

Intended workflow:

  1. Set up a layout with some inputs coming from external system using the Connectivity feature.
  2. Create a new empty recording and set the plugin to “Record IO” mode.
  3. Run the simulation at 1x speed along with the external system using the Connectivity feature.
  4. Reset simulation, optionally save the recording with the layout.
  5. Disconnect from any servers in Connectivity.
  6. Select the recording, set the plugin to “Replay IO” mode.
  7. Run the simulation slower or faster than realtime as you please.
  8. Optionally if used for “warmup”, you can connect to the external system once playback has finished.

Here is a Connectivity performance test / demo layout with 2 recordings. However, this particular layout doesn’t run much faster than realtime with IO playback because it is a stress test.
More realistic use cases should run the playback much faster.
Pixels demo with recording.vcmx (14.8 MB)

6 Likes

Hi,

This is a great add-on.

Where is the recorded information stored?
For example, it would be very useful to be able to input and output in Excel in the form of a time chart.

Thanks

The recordings are embedded into the vcmx file as binary data and not really possible to extract manually.

Some kind of file based import and export would be feasible to implement, but a significant problem is that e.g. in simple “csv” format the recordings would easily grow to hundreds of megabytes or more. The format must in practice be such that each IO variable is defined once (and given a numeric id) and then all value changes across all variables are listed in simulation time order without repeating the “variable names”.

This kind of data is best stored in a time series database.

Hi,
I have an issue regarding the saving of the recordings.

The recordings are not being saved with the vcmx-file. Im using the ABB Robot Connectivity in VC 4.6, but have also been trubble shooting on a VC 4.5 version with OPC UA without success.

The “Save in vcmx file” checkbox is ticked, but the recordings are not there when I re-open the file.
The recording is working as long as the file is open, so I can do multiple recordings and replay them but they are not there when I reopen the file.

I made a simple test with OPC UA in VC 4.6 Premium and the recording was saved and loaded fine.
It might be that for some reason the recorded data serialization fails, which could happen with unsupported data types such as vectors or matrices.

Please check if the VC error log file has any relevant error messages.

I’m only reading/recording real values…

This is what it said when I tried to load:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.Serialization.SerializationException: Expecting element 'SerializedConfiguration' from namespace 'http://schemas.datacontract.org/2004/07/IORecordAndReplay'.. Encountered 'None'  with name '', namespace ''. 
   at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
   at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
   at IORecordAndReplay.SerializedConfiguration.DeserializeFromBinary(Byte[] config)
   at IORecordAndReplay.MainPanelViewModel.LoadRecordings(String config, Boolean isSerializedAsBinary)
   at IORecordAndReplay.MainPanelViewModel.Application_LayoutLoadedEventHandler(Object sender, LayoutLoadedEventArgs e)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Delegate.DynamicInvokeImpl(Object[] args)
   at VisualComponents.Revolution.EventHelper.CallEventHandlers(Object source, Delegate[] invocationList, String filter, EventArgs args, String handlerName, Boolean showAllExceptions, Boolean showByPrinting, Boolean throwErrors)

This is what it says when saving:

2022-11-30 13:28:29,602 ERROR - Error in LayoutSaving.
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.Serialization.SerializationException: Type 'VisualComponents.Connectivity.Core.DofVariableInfo' with data contract name 'SimulationDofVariable:http://schemas.datacontract.org/2004/07/VisualComponents.Connectivity.Core' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiType(XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
   at WriteArrayOfSimulationVariableToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract )
   at System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerializeReference(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
   at WriteIORecordingToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , ClassDataContract )
   at System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
   at WriteArrayOfIORecordingToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract )
   at System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerializeReference(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
   at WriteSerializedConfigurationToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , ClassDataContract )
   at System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
   at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
   at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectContentHandleExceptions(XmlWriterDelegator writer, Object graph)
   at IORecordAndReplay.SerializedConfiguration.SerializeToBinary(Object objToSerialize)
   at IORecordAndReplay.MainPanelViewModel.SerializeConfiguration(Boolean serializeAsBinary)
   at IORecordAndReplay.MainPanelViewModel.Application_LayoutSavingEventHandler(Object sender, LayoutSavingEventArgs e)

From the error seems that saving data for variable pairs where the simulation side is a DOF object (robot joint) won’t work. I guess I’ll need to update the add-on to fix this issue when I get a change.

Thanks, that would be very much appreciated!
Its a great addon and I would like to use it to record robot movements.

best regards

Seems that I can’t modify the original post anymore.

Here is the add-on updated for VC 4.6 and the saving of robot joint data fixed. I think robot signal maps also had same issue, but I didn’t test yet whether those got fixed too.
IO record and replay add-on.zip (15.5 KB)

4 Likes

Wow, thank you! That was quick!
Works excellent!

2 Likes

Hi, is there a way to export data to a *.csv file or to a server database in // of embeded data into *.vcmx file?

The post has been edited, The add-on should be the latest on now in the OP.

2 Likes

Hi. Thank you for your answer.
but I would like to record the input and output by connecting PLC data from M200~M1699. Tell us more about the data pair in connectivity

  1. Set up a layout with some inputs coming from external system using the Connectivity feature.
    ↑ Please explain this part in detail.It’s hard to understand.

Please just see the Connectivity lessons in VC academy: