viatra / massif

Massif is a Matlab Simulink Integration Framework for Eclipse
https://viatra.github.io/massif/
Eclipse Public License 1.0
19 stars 14 forks source link

Exceptions importing Matlab's LKATestBenchExample #206

Closed adisandro closed 3 years ago

adisandro commented 3 years ago

Hi,

I'm trying to evaluate Massif for an automotive project at the University of Toronto. I'm using the 'LKATestBenchExample' that comes with Matlab and trying to convert it to a Massif model, using the latest CLI package from here: https://build.incquerylabs.com/jenkins/job/Massif/job/master/lastSuccessfulBuild/artifact/releng/hu.bme.mit.massif.simulink.cli-package/ I'm on Debian linux, running Matlab 2020b. I know you give compatibility until Matlab 2018b, but that's what I have.

If I run: modelExporter.createSimulinkModel('LKARefMdl', pwd, hu.bme.mit.massif.simulink.api.util.ImportMode.DEEP); (it's a sub-component of the bigger example) I get: Exception in thread "Thread-44": java.lang.UnsupportedOperationException at java.util.Collections$UnmodifiableList.remove(Collections.java:1317) at hu.bme.mit.massif.simulink.api.util.bus.BusSignalMappingCreator.storeFragmentsInMap(BusSignalMappingCreator.java:219) at hu.bme.mit.massif.simulink.api.util.bus.BusSignalMappingCreator.initializeFragmentResolutionMap(BusSignalMappingCreator.java:206) at hu.bme.mit.massif.simulink.api.util.bus.BusSignalMappingCreator.createBusMappingUsingCreator(BusSignalMappingCreator.java:193) at hu.bme.mit.massif.simulink.api.util.bus.BusSignalMappingCreator.findCreatorAndCreateBusMapping(BusSignalMappingCreator.java:91) at hu.bme.mit.massif.simulink.api.util.bus.BusSignalMappingCreator.createBusMapping(BusSignalMappingCreator.java:60) at hu.bme.mit.massif.simulink.api.Importer.createBusSignalMappings(Importer.java:661) at hu.bme.mit.massif.simulink.api.Importer.traverseAndCreateEMFModel(Importer.java:638) at hu.bme.mit.massif.simulink.cli.CLIEMFCreator$1.run(CLIEMFCreator.java:65) at java.lang.Thread.run(Thread.java:748) This is because the Splitter.splitToList returns an unmodifiable list, you should probably use Splitter.split instead if you want to remove an element later on.

If I run: modelExporter.createSimulinkModel('LKATestBenchExample', pwd, hu.bme.mit.massif.simulink.api.util.ImportMode.DEEP); I get: Exception in thread "Thread-53": java.lang.NullPointerException at hu.bme.mit.massif.simulink.api.ModelObject.getLoadPath(ModelObject.java:114) at hu.bme.mit.massif.simulink.api.Importer.traverseAndCreateEMFModel(Importer.java:563) at hu.bme.mit.massif.simulink.api.adapter.block.ModelReferenceAdapter.traverseReferencedModel(ModelReferenceAdapter.java:147) at hu.bme.mit.massif.simulink.api.adapter.block.ModelReferenceAdapter.process(ModelReferenceAdapter.java:88) at hu.bme.mit.massif.simulink.api.Importer.createBlockInstance(Importer.java:934) at hu.bme.mit.massif.simulink.api.Importer.createBlock(Importer.java:870) at hu.bme.mit.massif.simulink.api.Importer.createBlocksFromTopLevel(Importer.java:804) at hu.bme.mit.massif.simulink.api.Importer.traverseAndCreateEMFModel(Importer.java:620) at hu.bme.mit.massif.simulink.cli.CLIEMFCreator$1.run(CLIEMFCreator.java:65) at java.lang.Thread.run(Thread.java:748)

What is the status of this project? Is it still actively maintained? I can't make Massif work in Eclipse using the instructions for the MatlabEngine connector, it never appears as a connector option in the preferences. I'm pretty sure it boils down to the weird Java 8 ext mechanism, I just can't figure it out. The only way to make it work is using the CLI package, and that's ok. Trivial Simulink models work fine, but I'm more interested in complex ones.

Thank you!

abelhegedus commented 3 years ago

Hi,

this project is in maintenance mode. We do monitor the issue tracker and provide help in setting things up (see #205 or #201) and we also use it in customer projects and make changes where needed. It is also an open source project that welcomes contributions.

Yes, due to Matlab licensing issues, the MatlabEngine connector is really hard to get to work, if you provide some details on what you tried, we may be able to point to the missing step.

As for the exceptions, the bus mapping was working for sure at some point, but there may be a case that you are hitting that was not tested. If you can provide a PR, I can help you get the build results to try. It would probably be better to copy the results to a new mutable list instead.

Finally, thegetLoadPath NPE is really strange, since the path is set by the CLIEMFCreator on the ModeObject...

adisandro commented 3 years ago

Hi Abel,

I'm happy to do a PR for the mutable list.

For the other exception, I would have to debug what happens in the source code. How hard is it to set up a building system for the CLI package locally? In alternative, I have to make the MatlabEngine connector work in my setup. Can you tell me which exact version of Eclipse would you like me to use for that? I would run it with the jre that is embedded with Matlab under $MATLAB_DIR/sys/java/jre/glnxa64/jre, is that ok?

abelhegedus commented 3 years ago

I assume you read https://viatra.github.io/massif/user/matlab_connectors.html#me . We never tried directly using the Matlab JRE, but it may work depending on what version it is and what version of Eclipse you use.

Setting up the development environment or building from the command line are described in https://github.com/viatra/massif/wiki/Developer-Guide

If you set up your Eclipse with Oomph, you should be able to use newer IDE but for the Target platform Photon is the last one to be configured.

adisandro commented 3 years ago

Thanks for the quick review. I still plan to look at the second exception, but I won't have time for a couple of days.

Setting up a Photon dev environment with Oomph didn't go smooth, it could not complete and I ended up with building errors. No huge deal, I did it manually from a clean Eclipse, which I prefer anyway, but it took some time to find all the dependencies and I didn't try to run it in a second Eclipse instance yet. I'll probably ask you more questions about the MatlabEngine at that point.

adisandro commented 3 years ago

I'm back at it. The exception is different when running in Eclipse, it looks like the CLI is swallowing it and returning the strange NPE. Here is what I get: !ENTRY hu.bme.mit.massif.simulink.ui 4 0 2021-03-25 18:40:23.092 !MESSAGE Exception occurred while importing model! !STACK 0 hu.bme.mit.massif.communication.CommandEvaluationException: Exception occurred while evaluating command! at hu.bme.mit.massif.communication.AbstractCommandEvaluator.evaluateCommand(AbstractCommandEvaluator.java:65) at hu.bme.mit.massif.communication.matlabengine.MatlabEngineEvaluator.evaluateCommand(MatlabEngineEvaluator.java:45) at hu.bme.mit.massif.communication.AbstractCommandEvaluator.evaluateCommands(AbstractCommandEvaluator.java:264) at hu.bme.mit.massif.communication.command.MatlabCommand.execute(MatlabCommand.java:99) at hu.bme.mit.massif.simulink.api.adapter.block.DefaultBlockAdapter.process(DefaultBlockAdapter.java:56) at hu.bme.mit.massif.simulink.api.Importer.createBlockInstance(Importer.java:934) at hu.bme.mit.massif.simulink.api.Importer.createBlock(Importer.java:870) at hu.bme.mit.massif.simulink.api.Importer.createBlocksFromTopLevel(Importer.java:804) at hu.bme.mit.massif.simulink.api.Importer.traverseAndCreateEMFModel(Importer.java:620) at hu.bme.mit.massif.simulink.ui.handlers.ImportModelHandler$1.run(ImportModelHandler.java:196) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:60) Caused by: com.mathworks.engine.UnsupportedTypeException: Data Conversion Error for type: Simulink.HMI.SignalSpecification at com.mathworks.engine.FutureResult.get(FutureResult.java:57) at com.mathworks.engine.MatlabEngine.getVariable(MatlabEngine.java:567) at hu.bme.mit.massif.communication.matlabengine.MatlabEngineAccess.executeEval(MatlabEngineAccess.java:43) at hu.bme.mit.massif.communication.matlabengine.MatlabEngineEvaluator.dataRetriever(MatlabEngineEvaluator.java:50) at hu.bme.mit.massif.communication.AbstractCommandEvaluator.evaluateCommand(AbstractCommandEvaluator.java:58) ... 10 more And this is the last ImporterTmpResult:

ImporterTmpResult =

struct with fields:

                                    Name: 'Assist Status'
                                     Tag: ''
                             Description: ''
                           Type_READONLY: 'block'
                         Parent_READONLY: 'LKATestBenchExample'
                         Handle_READONLY: 4.3806e+04
                HiliteAncestors_READONLY: 'none'
                         RequirementInfo: ''
                          Ports_READONLY: [0 0 0 0 0 0 0 0 0]
                                Position: [1145 384 1180 419]
                    Orientation_READONLY: 'right'
               PortRotationType_READONLY: 'default'
                         ForegroundColor: 'black'
                         BackgroundColor: 'white'
                              DropShadow: 'off'
                                  IOType: 'none'
                  NamePlacement_READONLY: 'normal'
                            NameLocation: 'bottom'
                                ShowName: 'on'
                       HideAutomaticName: 'off'
                                Priority: ''
                               Commented: 'off'
                   CodeProfilingOverride: 'inherit'
                  AttributesFormatString: ''
                       InstantiateOnLoad: 'off'
                     PolySpaceEndComment: ''
                   PolySpaceStartComment: ''
                           AncestorBlock: ''
                 ReferenceBlock_READONLY: ''
              SourceLibraryInfo_READONLY: ''
                          LibraryVersion: ''
                      UserDataPersistent: 'off'
                                UserData: []
               CompiledIsActive_READONLY: 'on'
            CompiledVariantInfo_READONLY: [1×1 struct]
                                 RTWdata: []
                                 HDLData: []
                             Diagnostics: ''
               DialogParameters_READONLY: [1×1 struct]
      IntrinsicDialogParameters_READONLY: [1×1 struct]
            AlgorithmParameters_READONLY: [1×1 struct]
   SecondaryAlgorithmParameters_READONLY: [1×1 struct]
             CompiledSampleTime_READONLY: [-1 0]
               InputSignalNames_READONLY: {1×0 cell}
              OutputSignalNames_READONLY: {1×0 cell}
            ModelParamTableInfo_READONLY: []
            StatePerturbationForJacobian: 'auto'
SCDEnableBlockLinearizationSpecification: 'off'
      SCDBlockLinearizationSpecification: []
                                 CopyFcn: ''
                               DeleteFcn: ''
                           UndoDeleteFcn: ''
                                 LoadFcn: ''
                           ModelCloseFcn: ''
                              PreSaveFcn: ''
                             PostSaveFcn: ''
                                 InitFcn: ''
                             PreStartFcn: ''
                                StartFcn: ''
                                PauseFcn: ''
                             ContinueFcn: ''
                                 StopFcn: ''
                           NameChangeFcn: ''
                            ClipboardFcn: ''
                              DestroyFcn: ''
                              PreCopyFcn: ''
                                 OpenFcn: ''
                                CloseFcn: ''
                            PreDeleteFcn: ''
                          ParentCloseFcn: ''
                                 MoveFcn: ''
                      BlockType_READONLY: 'LampBlock'
               BlockDescription_READONLY: 'Display a color that reflects an input value.'
                           BlockKeywords: ""
                     LinkStatus_READONLY: 'none'
               StaticLinkStatus_READONLY: 'none'
               PortConnectivity_READONLY: [0×1 struct]
                    PortHandles_READONLY: [1×1 struct]
                    LineHandles_READONLY: [1×1 struct]
             CompiledPortWidths_READONLY: [0×0 struct]
         CompiledPortDimensions_READONLY: [0×0 struct]
          CompiledPortDataTypes_READONLY: [0×0 struct]
              CompiledPortUnits_READONLY: [0×0 struct]
     CompiledPortComplexSignals_READONLY: [0×0 struct]
          CompiledPortFrameData_READONLY: [0×0 struct]
      DataTypeOverride_Compiled_READONLY: 'UseLocalSettings'
 MinMaxOverflowLogging_Compiled_READONLY: 'UseLocalSettings'
                         IOSignalStrings: []
                  RuntimeObject_READONLY: []
                     ExtModeUploadOption: 'none'
        ExtModeLoggingSupported_READONLY: 'off'
                      ExtModeLoggingTrig: 'off'
      TargetArchitectureMapping_READONLY: {}
                                FontName: 'auto'
                                FontSize: -1
                              FontWeight: 'auto'
                               FontAngle: 'auto'
                       Selected_READONLY: 'off'
                           LabelPosition: 'Hide'
                                 Binding: [1×1 Simulink.HMI.SignalSpecification]
                         ShowInitialText: 'on'
                   ShowPropertyInspector: ''
                            ColorDefault: [0.9961 0.2000 0.0392]
                             StateColors: [1×1 struct]
                                MaskType: ''
                         MaskDescription: ''
                                MaskHelp: ''
                        MaskPromptString: ''
                         MaskStyleString: ''
                           MaskVariables: ''
                  MaskTunableValueString: ''
                      MaskCallbackString: ''
                        MaskEnableString: ''
                    MaskVisibilityString: ''
                       MaskToolTipString: ''
                      MaskVarAliasString: ''
                      MaskInitialization: ''
                      MaskSelfModifiable: 'off'
                             MaskDisplay: ''
                        MaskBlockDVGIcon: ''
                           MaskIconFrame: 'on'
                          MaskIconOpaque: 'opaque'
                          MaskIconRotate: 'none'
                          MaskPortRotate: 'default'
                           MaskIconUnits: 'autoscale'
                         MaskValueString: ''
                MaskRunInitForIconRedraw: 'analyze'
                       MaskTabNameString: ''
                                    Mask: 'off'
                           MaskCallbacks: {0×1 cell}
                             MaskEnables: {0×1 cell}
                      MaskNames_READONLY: {0×1 cell}
         MaskPropertyNameString_READONLY: ''
                             MaskPrompts: {0×1 cell}
                              MaskStyles: {0×1 cell}
                       MaskTunableValues: {0×1 cell}
                              MaskValues: {0×1 cell}
                     MaskToolTipsDisplay: {0×1 cell}
                        MaskVisibilities: {0×1 cell}
                          MaskVarAliases: {0×1 cell}
                MaskWSVariables_READONLY: []
                            MaskTabNames: {0×1 cell}
adisandro commented 3 years ago

Actually the load path NPE happens as well, but I have a PR incoming for it. I still don't have a clue about the above exception though.

abelhegedus commented 3 years ago

Caused by: com.mathworks.engine.UnsupportedTypeException: Data Conversion Error for type: Simulink.HMI.SignalSpecification

This is the relevant part. See https://www.mathworks.com/help/matlab/matlab_external/trouble-shooting-matlab-engine-api-exceptions.html

Can you check the result of the getMessage in this specific case?

adisandro commented 3 years ago

getMessage returns a not very helpful same string Data Conversion Error for type: Simulink.HMI.SignalSpecification.

adisandro commented 3 years ago

As far as I understand, Matlab's Java api fails to convert that type of object when using engine.getVariable. I don't think there's anything to be done other than skipping it. I'll create a PR, let me know if you agree with it.

abelhegedus commented 3 years ago

As far as I understand, Matlab's Java api fails to convert that type of object when using engine.getVariable. I don't think there's anything to be done other than skipping it. I'll create a PR, let me know if you agree with it.

Yes, that was exactly what I was thinking, catch and identify the error, log it and then move on.

adisandro commented 3 years ago

Yes, that was exactly what I was thinking, catch and identify the error, log it and then move on.

I filtered it in the matlab functions because I think that's where I should intercept it and made a PR for it. Let me know if you think it's not the right approach.

In the meantime, I'm on to the next exception I get: !ENTRY hu.bme.mit.massif.simulink.ui 4 0 2021-03-29 18:20:05.340 !MESSAGE Exception occurred while importing model! !STACK 0 java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.rangeCheck(ArrayList.java:659) at java.util.ArrayList.get(ArrayList.java:435) at hu.bme.mit.massif.communication.datatype.CellMatlabData.getData(CellMatlabData.java:43) at hu.bme.mit.massif.simulink.api.adapter.block.PortAdapter.processBusObject(PortAdapter.java:98) at hu.bme.mit.massif.simulink.api.adapter.block.PortAdapter.process(PortAdapter.java:54) at hu.bme.mit.massif.simulink.api.adapter.block.InportBlockAdapter.process(InportBlockAdapter.java:34) at hu.bme.mit.massif.simulink.api.Importer.createBlockInstance(Importer.java:934) at hu.bme.mit.massif.simulink.api.Importer.createBlock(Importer.java:870) at hu.bme.mit.massif.simulink.api.Importer.createBlocksFromTopLevel(Importer.java:804) at hu.bme.mit.massif.simulink.api.Importer.traverseAndCreateEMFModel(Importer.java:620) at hu.bme.mit.massif.simulink.api.adapter.block.ModelReferenceAdapter.traverseReferencedModel(ModelReferenceAdapter.java:148) at hu.bme.mit.massif.simulink.api.adapter.block.ModelReferenceAdapter.process(ModelReferenceAdapter.java:88) at hu.bme.mit.massif.simulink.api.Importer.createBlockInstance(Importer.java:934) at hu.bme.mit.massif.simulink.api.Importer.createBlock(Importer.java:870) at hu.bme.mit.massif.simulink.api.Importer.createBlocksFromTopLevel(Importer.java:804) at hu.bme.mit.massif.simulink.api.Importer.traverseAndCreateEMFModel(Importer.java:620) at hu.bme.mit.massif.simulink.ui.handlers.ImportModelHandler$1.run(ImportModelHandler.java:196) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:60)

abelhegedus commented 3 years ago

PortAdapter expects the bus object to have some content, but it may be that this example contains some that have not. As always, you should check where in the model the exception occurs (it would be really nice to keep track of the traversal location in the importer and include that when printing the exception).

https://github.com/viatra/massif/blob/804cbca1ac0ddce33d4c7f46d6d46db1f137c535/plugins/hu.bme.mit.massif.simulink.api/src/hu/bme/mit/massif/simulink/api/adapter/block/PortAdapter.java#L98

adisandro commented 3 years ago

As always, you should check where in the model the exception occurs

Yes I do find where it happens, but I'm also posting it here in case you've seen the problem already.

it would be really nice to keep track of the traversal location in the importer

I use the 'Print Issued Commands' option in Massif's configuration menu to do that.

PortAdapter expects the bus object to have some content, but it may be that this example contains some that have not.

In this case it has content, but it is not parsed. MatlabEngineEvaluator.convertToMatlabData skips mixed cell arrays completely (from this table https://www.mathworks.com/help/matlab/matlab_external/data-type-conversions.html). I am making a PR for it.

adisandro commented 3 years ago

Here's the next one, with a PR to fix it:

!ENTRY hu.bme.mit.massif.simulink.ui 4 0 2021-03-30 03:45:54.723 !MESSAGE Exception occurred while importing model! !STACK 0 java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.rangeCheck(ArrayList.java:659) at java.util.ArrayList.get(ArrayList.java:435) at hu.bme.mit.massif.communication.datatype.CellMatlabData.getData(CellMatlabData.java:43) at hu.bme.mit.massif.simulink.api.adapter.block.InportShadowAdapter.process(InportShadowAdapter.java:39) at hu.bme.mit.massif.simulink.api.Importer.createBlockInstance(Importer.java:934) at hu.bme.mit.massif.simulink.api.Importer.createBlock(Importer.java:870) at hu.bme.mit.massif.simulink.api.Importer.createBlocksFromSubBlocks(Importer.java:840) at hu.bme.mit.massif.simulink.api.Importer.createBlock(Importer.java:886) at hu.bme.mit.massif.simulink.api.Importer.createBlocksFromSubBlocks(Importer.java:840) at hu.bme.mit.massif.simulink.api.Importer.createBlock(Importer.java:886) at hu.bme.mit.massif.simulink.api.Importer.createBlocksFromSubBlocks(Importer.java:840) at hu.bme.mit.massif.simulink.api.Importer.createBlock(Importer.java:886) at hu.bme.mit.massif.simulink.api.Importer.createBlocksFromSubBlocks(Importer.java:840) at hu.bme.mit.massif.simulink.api.Importer.createBlock(Importer.java:886) at hu.bme.mit.massif.simulink.api.Importer.createBlocksFromSubBlocks(Importer.java:840) at hu.bme.mit.massif.simulink.api.Importer.createBlock(Importer.java:886) at hu.bme.mit.massif.simulink.api.Importer.createBlocksFromSubBlocks(Importer.java:840) at hu.bme.mit.massif.simulink.api.Importer.createBlock(Importer.java:886) at hu.bme.mit.massif.simulink.api.Importer.createBlocksFromSubBlocks(Importer.java:840) at hu.bme.mit.massif.simulink.api.Importer.createBlock(Importer.java:886) at hu.bme.mit.massif.simulink.api.Importer.createBlocksFromSubBlocks(Importer.java:840) at hu.bme.mit.massif.simulink.api.Importer.createBlock(Importer.java:886) at hu.bme.mit.massif.simulink.api.Importer.createBlocksFromSubBlocks(Importer.java:840) at hu.bme.mit.massif.simulink.api.Importer.createBlock(Importer.java:886) at hu.bme.mit.massif.simulink.api.Importer.createBlocksFromTopLevel(Importer.java:804) at hu.bme.mit.massif.simulink.api.Importer.traverseAndCreateEMFModel(Importer.java:620) at hu.bme.mit.massif.simulink.ui.handlers.ImportModelHandler$1.run(ImportModelHandler.java:196) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:60)

adisandro commented 3 years ago

And another Matlab type api failure: Caused by: com.mathworks.engine.UnsupportedTypeException: Data Conversion Error for type: mpc

I'm updating the existing PR #209 to skip this type too.

adisandro commented 3 years ago

Thank you for the quick reviews! Next exception:

!ENTRY hu.bme.mit.massif.simulink.ui 4 0 2021-03-31 03:37:55.700 !MESSAGE Exception occurred while importing model! !STACK 0 java.lang.IndexOutOfBoundsException: Index: 5, Size: 1 at java.util.ArrayList.rangeCheck(ArrayList.java:659) at java.util.ArrayList.get(ArrayList.java:435) at hu.bme.mit.massif.simulink.api.adapter.block.PortAdapter.processBusObject(PortAdapter.java:107) at hu.bme.mit.massif.simulink.api.adapter.block.PortAdapter.process(PortAdapter.java:54) at hu.bme.mit.massif.simulink.api.adapter.block.InportBlockAdapter.process(InportBlockAdapter.java:34) at hu.bme.mit.massif.simulink.api.Importer.createBlockInstance(Importer.java:934) at hu.bme.mit.massif.simulink.api.Importer.createBlock(Importer.java:870) at hu.bme.mit.massif.simulink.api.Importer.createBlocksFromTopLevel(Importer.java:804) at hu.bme.mit.massif.simulink.api.Importer.traverseAndCreateEMFModel(Importer.java:620) at hu.bme.mit.massif.simulink.api.adapter.block.ModelReferenceAdapter.traverseReferencedModel(ModelReferenceAdapter.java:148) at hu.bme.mit.massif.simulink.api.adapter.block.ModelReferenceAdapter.process(ModelReferenceAdapter.java:88) at hu.bme.mit.massif.simulink.api.Importer.createBlockInstance(Importer.java:934) at hu.bme.mit.massif.simulink.api.Importer.createBlock(Importer.java:870) at hu.bme.mit.massif.simulink.api.Importer.createBlocksFromTopLevel(Importer.java:804) at hu.bme.mit.massif.simulink.api.Importer.traverseAndCreateEMFModel(Importer.java:620) at hu.bme.mit.massif.simulink.ui.handlers.ImportModelHandler$1.run(ImportModelHandler.java:196) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:60)

I'll make a PR shortly, and I can happily say that by fixing this I'm finally able to import the whole model correctly.

adisandro commented 3 years ago

Thank you for the assistance with this! I'll close the bug and will be in touch if I run into other issues while using Massif.

abelhegedus commented 3 years ago

Thank you for contributing with these fixes!