Exemplo n.º 1
0
def validate_cross_check_result(result_dir):
    """ Validate a cross-check result

    Parameters:
        result_dir  path to the directory that contains the results

    Returns:
        a list of problems
    """

    problems = []

    if os.path.isfile(os.path.join(result_dir, 'notCompliantWithLatestRules')):
        return problems

    # check ReadMe
    if not os.path.isfile(os.path.join(
            result_dir, 'ReadMe.txt')) and not os.path.isfile(
                os.path.join(result_dir, 'ReadMe.pdf')):
        problems.append("Readme.[txt|pdf] is missing in %s" % result_dir)

    if not os.path.isfile(os.path.join(result_dir, 'passed')):
        return problems

    _, model_name = os.path.split(result_dir)

    # check the output file
    csv_filename = os.path.join(result_dir, model_name + '_out.csv')

    try:
        read_csv(csv_filename)
    except Exception as e:
        problems.append("Error in %s. %s" % (csv_filename, e))

    return problems
Exemplo n.º 2
0
    def validate(self, build_dir, fmi_types=['ModelExchange', 'CoSimulation'], models=models, compile=False):

        from fmpy.util import read_csv, validate_result

        for model in models:

            print(model)

            fmu_filename = os.path.join(build_dir, 'dist', model + '.fmu')

            if model == 'Feedthrough':
                start_values = {'real_fixed_param': 1, 'string_param': "FMI is awesome!"}
                in_csv = os.path.join(test_fmus_dir, model, model + '_in.csv')
                input = read_csv(in_csv)
            else:
                start_values = {}
                input = None

            ref_csv = os.path.join(test_fmus_dir, model, model + '_ref.csv')

            for fmi_type in fmi_types:

                ref = read_csv(ref_csv)

                if compile:
                    compile_platform_binary(fmu_filename)

                result = simulate_fmu(fmu_filename,
                                      fmi_type=fmi_type,
                                      start_values=start_values,
                                      input=input)

                dev = validate_result(result, ref)

                self.assertLess(dev, 0.2, "Failed to validate " + model)
Exemplo n.º 3
0
    def test_structured_csv(self):

        cols = [
            ('time', np.float64, None),
            ('y', np.float64, (3,)),
        ]

        rows = [
            (0.0, (1.0, 2.0, 3.0)),
            (0.1, (1.1, 2.1, 3.1)),
            (0.2, (1.2, 2.2, 3.2)),
            (0.3, (1.3, 2.3, 3.3)),
        ]

        # create a structured array with a 1-d array signal
        result = np.array(rows, dtype=np.dtype(cols))

        # arrays are saved as single columns
        write_csv('structured.csv', result)

        # read as-is (single columns)
        traj = read_csv('structured.csv')

        self.assertEqual(traj.dtype.names, ('time', 'y[1]', 'y[2]', 'y[3]'))

        # read structured (restore arrays)
        traj = read_csv('structured.csv', structured=True)

        self.assertEqual(traj.dtype.names, ('time', 'y'))
        self.assertEqual(traj['y'].shape, (4, 3))
Exemplo n.º 4
0
def simulate(options):

    # read the input file
    if 'input_filename' in options:
        input = read_csv(options['input_filename'])
    else:
        input = None

    step_size = options['step_size']

    # select solver based on step_size
    if step_size > 0:
        solver = 'Euler'
    else:
        solver = 'CVode'

    solver = 'CVode'

    # simulate the FMU
    result = fmpy.simulate_fmu(filename=options['fmu_filename'],
                               validate=False,
                               solver=solver,
                               step_size=step_size,
                               stop_time=options['stop_time'],
                               input=input,
                               output=options['output_variable_names'],
                               timeout=5)

    return result
Exemplo n.º 5
0
def validate(build_dir, fmi_types, models, compile=False):

    from fmpy.util import read_csv, validate_result

    test_fmus_dir = Path(__file__).parent

    for model in models:

        print(model)

        fmu_filename = os.path.join(build_dir, 'dist', model + '.fmu')

        problems = validate_fmu(fmu_filename)

        assert not problems

        if model == 'Feedthrough':
            start_values = {'Float64_fixed_parameter': 1, 'String_parameter': "FMI is awesome!"}
            in_csv = os.path.join(test_fmus_dir, model, model + '_in.csv')
            input = read_csv(in_csv)
        else:
            start_values = {}
            input = None

        ref_csv = os.path.join(test_fmus_dir, model, model + '_ref.csv')

        for fmi_type in fmi_types:

            ref = read_csv(ref_csv)

            if compile:
                if model == 'Resource' and os.name == 'nt':
                    continue
                compile_platform_binary(fmu_filename)

            result = simulate_fmu(fmu_filename,
                                  fmi_type=fmi_type,
                                  start_values=start_values,
                                  input=input,
                                  solver='Euler')

            dev = validate_result(result, ref)

            assert dev < 0.2, "Failed to validate " + model
Exemplo n.º 6
0
def simulate(options):

    # read the input file
    if 'input_filename' in options:
        input = read_csv(options['input_filename'])
    else:
        input = None

    # simulate the FMU
    result = fmpy.simulate_fmu(filename=options['fmu_filename'],
                               validate=False,
                               step_size=options['step_size'],
                               stop_time=options['stop_time'],
                               input=input,
                               output=options['output_variable_names'])

    return result
Exemplo n.º 7
0
def main():

    import argparse
    import textwrap

    description = """\
    Validate and simulate Functional Mock-up Units (FMUs)

    Get information about an FMU:
       
        fmpy info Rectifier.fmu
     
    Simulate an FMU:
     
        fmpy simulate Rectifier.fmu --show-plot
        
    Compile a source code FMU:
    
        fmpy compile Rectifier.fmu
        
    Create a Jupyter Notebook
    
        fmpy create-jupyter-notebook Rectifier.fmu
    """

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description=textwrap.dedent(description))

    parser.add_argument('command',
                        choices=[
                            'info', 'validate', 'simulate', 'compile',
                            'add-cswrapper', 'add-remoting',
                            'create-cmake-project', 'create-jupyter-notebook'
                        ],
                        help="Command to execute")
    parser.add_argument('fmu_filename', help="filename of the FMU")

    parser.add_argument('--validate',
                        action='store_true',
                        help="validate the FMU")
    parser.add_argument('--start-time',
                        type=float,
                        help="start time for the simulation")
    parser.add_argument('--stop-time',
                        type=float,
                        help="stop time for the simulation")
    parser.add_argument('--solver',
                        choices=['Euler', 'CVode'],
                        default='CVode',
                        help="solver to use for Model Exchange")
    parser.add_argument('--step-size',
                        type=float,
                        help="step size for fixed-step solvers")
    parser.add_argument(
        '--relative-tolerance',
        type=float,
        help=
        "relative tolerance for the 'CVode' solver and FMI 2.0 co-simulation FMUs"
    )
    parser.add_argument(
        '--dont-record-events',
        action='store_true',
        help="dont't record outputs at events (model exchange only)")
    parser.add_argument('--start-values',
                        nargs='+',
                        help="name-value pairs of start values")
    parser.add_argument(
        '--apply-default-start-values',
        action='store_true',
        help="apply the start values from the model description")
    parser.add_argument('--output-interval',
                        type=float,
                        help="interval for sampling the output")
    parser.add_argument('--input-file', help="CSV file to use as input")
    parser.add_argument('--output-variables',
                        nargs='+',
                        help="Variables to record")
    parser.add_argument('--output-file', help="CSV to store the results")
    parser.add_argument('--timeout',
                        type=float,
                        help="max. time to wait for the simulation to finish")
    parser.add_argument('--debug-logging',
                        action='store_true',
                        help="enable the FMU's debug logging")
    parser.add_argument('--visible',
                        action='store_true',
                        help="enable interactive mode")
    parser.add_argument('--fmi-logging',
                        action='store_true',
                        help="enable FMI logging")
    parser.add_argument('--show-plot',
                        action='store_true',
                        help="plot the results")
    parser.add_argument('--cmake-project-dir',
                        help="Directory for the CMake project")
    parser.add_argument('--target-platform',
                        help="The target platform to compile the binary for")

    args = parser.parse_args()

    if args.command == 'info':

        from fmpy import dump
        dump(args.fmu_filename)

    elif args.command == 'validate':

        import sys
        from fmpy.validation import validate_fmu

        problems = validate_fmu(args.fmu_filename)

        if len(problems) == 0:
            print('No problems found.')
        else:
            print('%d problems were found:' % len(problems))
            for message in problems:
                print()
                print(message)

        sys.exit(len(problems))

    elif args.command == 'compile':

        from fmpy.util import compile_platform_binary
        compile_platform_binary(args.fmu_filename,
                                target_platform=args.target_platform)

    elif args.command == 'add-cswrapper':

        from fmpy.cswrapper import add_cswrapper
        add_cswrapper(args.fmu_filename)

    elif args.command == 'add-remoting':

        from fmpy.util import add_remoting
        from fmpy import supported_platforms

        platforms = supported_platforms(args.fmu_filename)

        if 'win32' in platforms and 'win64' not in platforms:
            add_remoting(args.fmu_filename, 'win64', 'win32')
        elif 'win64' in platforms and 'linux64' not in platforms:
            add_remoting(args.fmu_filename, 'linux64', 'win64')
        else:
            print("Failed to add remoting binaries.")

    elif args.command == 'create-cmake-project':

        import os
        from fmpy.util import create_cmake_project

        project_dir = args.cmake_project_dir

        if project_dir is None:
            project_dir = os.path.basename(args.fmu_filename)
            project_dir, _ = os.path.splitext(project_dir)
            print("Creating CMake project in %s" %
                  os.path.abspath(project_dir))

        create_cmake_project(args.fmu_filename, project_dir)

    elif args.command == 'create-jupyter-notebook':

        from fmpy.util import create_jupyter_notebook

        create_jupyter_notebook(args.fmu_filename)

    elif args.command == 'simulate':

        from fmpy import simulate_fmu
        from fmpy.util import read_csv, write_csv, plot_result

        if args.start_values:
            if len(args.start_values) % 2 != 0:
                raise Exception("Start values must be name-value pairs.")
            start_values = {
                k: v
                for k, v in zip(args.start_values[::2],
                                args.start_values[1::2])
            }
        else:
            start_values = {}

        input = read_csv(args.input_file) if args.input_file else None

        if args.fmi_logging:
            fmi_call_logger = lambda s: print('[FMI] ' + s)
        else:
            fmi_call_logger = None

        result = simulate_fmu(
            args.fmu_filename,
            validate=args.validate,
            start_time=args.start_time,
            stop_time=args.stop_time,
            solver=args.solver,
            step_size=args.step_size,
            relative_tolerance=args.relative_tolerance,
            output_interval=args.output_interval,
            record_events=not args.dont_record_events,
            fmi_type=None,
            start_values=start_values,
            apply_default_start_values=args.apply_default_start_values,
            input=input,
            output=args.output_variables,
            timeout=args.timeout,
            debug_logging=args.debug_logging,
            visible=args.visible,
            fmi_call_logger=fmi_call_logger)

        if args.output_file:
            write_csv(filename=args.output_file, result=result)

        if args.show_plot:
            plot_result(result=result, window_title=args.fmu_filename)
Exemplo n.º 8
0
def main():

    import argparse
    import textwrap

    description = """\
    Validate and simulate Functional Mock-up Units (FMUs)

    Get information about an FMU:
       
        fmpy info Rectifier.fmu
     
    Simulate an FMU:
     
        fmpy simulate Rectifier.fmu --show-plot
        
    Compile a source code FMU:
    
        fmpy compile Rectifier.fmu
    """

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description=textwrap.dedent(description))

    parser.add_argument(
        'command',
        choices=['info', 'validate', 'simulate', 'compile', 'add-remoting'],
        help="Command to execute")
    parser.add_argument('fmu_filename', help="filename of the FMU")

    parser.add_argument('--validate',
                        action='store_true',
                        help="validate the FMU")
    parser.add_argument('--start-time',
                        type=float,
                        help="start time for the simulation")
    parser.add_argument('--stop-time',
                        type=float,
                        help="stop time for the simulation")
    parser.add_argument('--solver',
                        choices=['Euler', 'CVode'],
                        default='CVode',
                        help="solver to use for Model Exchange")
    parser.add_argument('--step-size',
                        type=float,
                        help="step size for fixed-step solvers")
    parser.add_argument(
        '--relative-tolerance',
        type=float,
        help=
        "relative tolerance for the 'CVode' solver and FMI 2.0 co-simulation FMUs"
    )
    parser.add_argument(
        '--dont-record-events',
        action='store_true',
        help="dont't record outputs at events (model exchange only)")
    parser.add_argument('--start-values',
                        nargs='+',
                        help="name-value pairs of start values")
    parser.add_argument(
        '--apply-default-start-values',
        action='store_true',
        help="apply the start values from the model description")
    parser.add_argument('--output-interval',
                        type=float,
                        help="interval for sampling the output")
    parser.add_argument('--input-file', help="CSV file to use as input")
    parser.add_argument('--output-variables',
                        nargs='+',
                        help="Variables to record")
    parser.add_argument('--output-file', help="CSV to store the results")
    parser.add_argument('--timeout',
                        type=float,
                        help="max. time to wait for the simulation to finish")
    parser.add_argument('--debug-logging',
                        action='store_true',
                        help="enable the FMU's debug logging")
    parser.add_argument('--visible',
                        action='store_true',
                        help="enable interactive mode")
    parser.add_argument('--fmi-logging',
                        action='store_true',
                        help="enable FMI logging")
    parser.add_argument('--show-plot',
                        action='store_true',
                        help="plot the results")

    args = parser.parse_args()

    if args.command == 'info':

        from fmpy import dump
        dump(args.fmu_filename)

    elif args.command == 'validate':

        import sys
        from fmpy.util import validate_fmu

        messages = validate_fmu(args.fmu_filename)

        if len(messages) == 0:
            print('The validation passed')
        else:
            print('The following errors were found:')
            for message in messages:
                print()
                print(message)
            sys.exit(1)

    elif args.command == 'compile':

        from fmpy.util import compile_platform_binary
        compile_platform_binary(args.fmu_filename)

    elif args.command == 'add-remoting':

        from fmpy.util import add_remoting
        add_remoting(args.fmu_filename)

    elif args.command == 'simulate':

        from fmpy import simulate_fmu
        from fmpy.util import read_csv, write_csv, plot_result

        if args.start_values:
            if len(args.start_values) % 2 != 0:
                raise Exception("Start values must be name-value pairs.")
            start_values = {
                k: v
                for k, v in zip(args.start_values[::2],
                                args.start_values[1::2])
            }
        else:
            start_values = {}

        input = read_csv(args.input_file) if args.input_file else None

        if args.fmi_logging:
            fmi_call_logger = lambda s: print('[FMI] ' + s)
        else:
            fmi_call_logger = None

        result = simulate_fmu(
            args.fmu_filename,
            validate=args.validate,
            start_time=args.start_time,
            stop_time=args.stop_time,
            solver=args.solver,
            step_size=args.step_size,
            relative_tolerance=args.relative_tolerance,
            output_interval=args.output_interval,
            record_events=not args.dont_record_events,
            fmi_type=None,
            start_values=start_values,
            apply_default_start_values=args.apply_default_start_values,
            input=input,
            output=args.output_variables,
            timeout=args.timeout,
            debug_logging=args.debug_logging,
            visible=args.visible,
            fmi_call_logger=fmi_call_logger)

        if args.output_file:
            write_csv(filename=args.output_file, result=result)

        if args.show_plot:
            plot_result(result=result, window_title=args.fmu_filename)
Exemplo n.º 9
0
def test_create_fmu_container_cs(resources_dir):

    configuration = Configuration(
        parallelDoStep=True,
        description="A controlled drivetrain",
        variableNamingConvention='structured',
        unitDefinitions=[
            Unit(name='rad/s',
                 baseUnit=BaseUnit(rad=1, s=-1),
                 displayUnits=[
                     DisplayUnit(name='rpm', factor=0.1047197551196598)
                 ])
        ],
        typeDefinitions=[
            SimpleType(name='AngularVelocity', type='Real', unit='rad/s')
        ],
        variables=[
            Variable(type='Real',
                     variability='tunable',
                     causality='parameter',
                     initial='exact',
                     name='k',
                     start='40',
                     description='Gain of controller',
                     mapping=[('controller', 'PI.k')]),
            Variable(type='Real',
                     variability='continuous',
                     causality='input',
                     name='w_ref',
                     start='0',
                     description='Reference speed',
                     mapping=[('controller', 'u_s')],
                     declaredType='AngularVelocity'),
            Variable(type='Real',
                     variability='continuous',
                     causality='output',
                     initial='calculated',
                     name='w',
                     description="Gain of controller",
                     mapping=[('drivetrain', 'w')],
                     unit='rad/s',
                     displayUnit='rpm'),
        ],
        components=[
            Component(filename=resources_dir / 'Controller.fmu',
                      interfaceType='CoSimulation',
                      name='controller'),
            Component(
                filename=resources_dir / 'Drivetrain.fmu',
                interfaceType='CoSimulation',
                name='drivetrain',
            )
        ],
        connections=[
            Connection('drivetrain', 'w', 'controller', 'u_m'),
            Connection('controller', 'y', 'drivetrain', 'tau'),
        ])

    filename = 'ControlledDrivetrain.fmu'

    create_fmu_container(configuration, filename)

    problems = validate_fmu(filename)

    assert not problems

    input = read_csv(resources_dir / 'ControlledDrivetrain_in.csv')

    result = simulate_fmu(filename,
                          input=input,
                          output=['w_ref', 'w', 'k'],
                          stop_time=5,
                          output_interval=5e-2)

    t_band, y_min, y_max, i_out = validate_signal(t=result['time'],
                                                  y=result['w'],
                                                  t_ref=input['time'],
                                                  y_ref=input['w_ref'],
                                                  dx=100,
                                                  dy=0.4)

    assert result['k'][0] == 40, 'Default start value has not been set.'

    assert not i_out.any()
Exemplo n.º 10
0
def validate_test_fmu(model_dir):
    """ Validate an exported FMU

    Parameters:
        model_dir  path to the directory that contains the exported FMU

    Returns:
        a list of problems
    """

    problems = []

    _, model_name = os.path.split(model_dir)

    if os.path.isfile(os.path.join(model_dir, 'notCompliantWithLatestRules')):
        return []

    fmu_filename = os.path.join(model_dir, model_name + '.fmu')

    # validate the modelDescription.xml
    try:
        model_description = read_model_description(fmu_filename, validate=True)
    except Exception as e:
        problems.append("Error in %s. %s" % (fmu_filename, e))
        return problems  # stop here

    # collect the variable names
    variable_names = [v.name for v in model_description.modelVariables]

    # check the reference options file
    try:
        ref_opts_filename = os.path.join(model_dir, model_name + '_ref.opt')
        read_ref_opt_file(ref_opts_filename)
    except Exception as e:
        problems.append("Error in %s. %s" % (ref_opts_filename, e))

    # check the CSVs
    for suffix, required in [('_cc.csv', True), ('_in.csv', False),
                             ('_ref.csv', True)]:

        csv_filename = os.path.join(model_dir, model_name + suffix)

        if not required and not os.path.isfile(csv_filename):
            continue

        try:
            read_csv(csv_filename, variable_names=variable_names)
        except Exception as e:
            problems.append("Error in %s. %s" % (csv_filename, e))

    # check compliance checker log file
    cc_logfile = model_name + '_cc.log'

    if not os.path.isfile(os.path.join(model_dir, cc_logfile)):
        problems.append("%s is missing in %s" % (cc_logfile, model_dir))

    # check ReadMe
    if not os.path.isfile(os.path.join(
            model_dir, 'ReadMe.txt')) and not os.path.isfile(
                os.path.join(model_dir, 'ReadMe.pdf')):
        problems.append("Readme.[txt|pdf] is missing in %s" % model_dir)

    if platform in ['win32', 'win64']:
        cc_script = model_name + '_cc.bat'
    else:
        cc_script = model_name + '_cc.sh'

    if not os.path.isfile(os.path.join(model_dir, cc_script)):
        problems.append("%s is missing in %s" % (cc_script, model_dir))

    return problems
Exemplo n.º 11
0
    def startSimulation(self):

        from fmpy.gui.simulation import SimulationThread

        try:
            start_time = float(self.startTimeLineEdit.text())
            stop_time = float(self.stopTimeLineEdit.text())
            step_size = float(self.ui.stepSizeLineEdit.text())
            relative_tolerance = float(
                self.ui.relativeToleranceLineEdit.text())

            if self.ui.outputIntervalRadioButton.isChecked():
                output_interval = float(self.ui.outputIntervalLineEdit.text())
            else:
                max_samples = float(self.ui.maxSamplesLineEdit.text())
                output_interval = stop_time / max_samples
        except Exception as ex:
            self.log.log('error', "Failed to start simulation: %s" % ex)
            self.ui.stackedWidget.setCurrentWidget(self.ui.logPage)
            return

        step_size = min(step_size, output_interval)

        if self.ui.solverComboBox.currentText() == 'Fixed-step':
            solver = 'Euler'
        else:
            solver = 'CVode'

        if self.ui.inputCheckBox.isChecked():

            input_variables = []
            for variable in self.modelDescription.modelVariables:
                if variable.causality == 'input':
                    input_variables.append(variable.name)
            try:
                from fmpy.util import read_csv
                filename = self.ui.inputFilenameLineEdit.text()
                input = read_csv(filename, variable_names=input_variables)
            except Exception as e:
                self.log.log(
                    'error',
                    "Failed to load input from '%s'. %s" % (filename, e))
                return
        else:
            input = None

        output = []
        for variable in self.modelDescription.modelVariables:
            output.append(variable.name)

        fmi_type = 'CoSimulation' if self.fmiTypeComboBox.currentText(
        ) == 'Co-Simulation' else 'ModelExchange'

        self.simulationThread = SimulationThread(
            filename=self.filename,
            fmiType=fmi_type,
            startTime=start_time,
            stopTime=stop_time,
            solver=solver,
            stepSize=step_size,
            relativeTolerance=relative_tolerance,
            outputInterval=output_interval,
            startValues=self.startValues,
            applyDefaultStartValues=self.ui.applyDefaultStartValuesCheckBox.
            isChecked(),
            input=input,
            output=output,
            debugLogging=self.ui.debugLoggingCheckBox.isChecked(),
            fmiLogging=self.ui.logFMICallsCheckBox.isChecked())

        self.ui.actionSimulate.setIcon(QIcon(':/icons/stop.png'))
        self.ui.actionSimulate.setToolTip("Stop simulation")
        self.ui.actionSimulate.triggered.disconnect(self.startSimulation)
        self.ui.actionSimulate.triggered.connect(self.simulationThread.stop)

        self.simulationProgressBar.setVisible(True)

        self.simulationThread.messageChanged.connect(self.log.log)
        self.simulationThread.progressChanged.connect(
            self.simulationProgressBar.setValue)
        self.simulationThread.finished.connect(self.simulationFinished)

        if self.ui.clearLogOnStartButton.isChecked():
            self.log.clear()

        self.setCurrentPage(self.ui.resultPage)

        self.simulationThread.start()
        self.plotUpdateTimer.start(100)

        self.updatePlotLayout()
Exemplo n.º 12
0
def main():

    import argparse
    import textwrap

    description = """\
    Simulate an FMU

    Example: 
        > python -m fmpy.simulate Rectifier.fmu

    """

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description=textwrap.dedent(description))

    parser.add_argument('command',
                        choices=['info', 'simulate'],
                        help="Command to execute")
    parser.add_argument('fmu_filename', help="filename of the FMU")

    parser.add_argument('--solver',
                        choices=['Euler', 'CVode'],
                        default='CVode',
                        help="solver to use for Model Exchange")
    parser.add_argument('--input-file', help="CSV file to use as input")
    parser.add_argument('--output-variables',
                        nargs='+',
                        help="Variables to record")
    parser.add_argument('--output-file', help="CSV to store the results")
    parser.add_argument('--num-samples',
                        default=500,
                        type=int,
                        help="number of samples to record")
    parser.add_argument('--step-size',
                        type=float,
                        help="step size for fixed-step solvers")
    parser.add_argument('--start-time',
                        type=float,
                        help="start time for the simulation")
    parser.add_argument('--stop-time',
                        type=float,
                        help="stop time for the simulation")
    parser.add_argument('--show-plot',
                        action='store_true',
                        help="plot the results")
    parser.add_argument('--timeout',
                        type=float,
                        help="max. time to wait for the simulation to finish")
    parser.add_argument('--fmi-logging',
                        action='store_true',
                        help="enable FMI logging")
    parser.add_argument('--start-values',
                        nargs='+',
                        help="name-value pairs of start values")

    args = parser.parse_args()

    if args.command == 'info':

        from fmpy import dump
        dump(args.fmu_filename)

    elif args.command == 'simulate':

        from fmpy import simulate_fmu
        from fmpy.util import read_csv, write_csv, plot_result

        if args.start_values:
            if len(args.start_values) % 2 != 0:
                raise Exception("Start values must be name-value pairs.")
            start_values = {
                k: v
                for k, v in zip(args.start_values[::2],
                                args.start_values[1::2])
            }
        else:
            start_values = {}

        input = read_csv(args.input_file) if args.input_file else None

        result = simulate_fmu(args.fmu_filename,
                              validate=True,
                              start_time=args.start_time,
                              stop_time=args.stop_time,
                              solver=args.solver,
                              step_size=args.step_size,
                              output_interval=None,
                              fmi_type=None,
                              start_values=start_values,
                              input=input,
                              output=args.output_variables,
                              timeout=args.timeout,
                              fmi_logging=args.fmi_logging)

        if args.output_file:
            write_csv(args.output_file, result)

        if args.show_plot:
            plot_result(result=result, window_title=args.fmu_filename)
Exemplo n.º 13
0
    ('Feedthrough',  {'real_fixed_param': 1}, 0.2),
    ('Resource',     {}, 0.2),
    ('Stair',        {}, 10),
    ('VanDerPol',    {}, 0.1),
]

for model_name, start_values, output_interval in info:
    print(model_name)
    fmu = os.path.join(dist_dir, model_name + '.fmu')

    ref_csv = os.path.join(src_dir, model_name, model_name + '_ref.csv')
    ref_png = os.path.join(src_dir, model_name, model_name + '_ref.svg')
    in_csv  = os.path.join(src_dir, model_name, model_name + '_in.csv')

    if os.path.isfile(in_csv):
        input = read_csv(in_csv)
    else:
        input = None

    result = simulate_fmu(fmu,
                          fmi_type='ModelExchange',
                          # solver='Euler',
                          start_values=start_values,
                          input=input,
                          output_interval=output_interval
                          )

    write_csv(ref_csv, result)
    ref = read_csv(ref_csv)
    plot_result(ref, events=True, filename=ref_png)
Exemplo n.º 14
0
    def startSimulation(self):

        from .simulation import SimulationThread

        # TODO: catch exceptions
        stop_time = float(self.stopTimeLineEdit.text())
        step_size = float(self.ui.stepSizeLineEdit.text())
        relative_tolerance = float(self.ui.relativeToleranceLineEdit.text())
        max_samples = float(self.ui.maxSamplesLineEdit.text())

        output_interval = stop_time / max_samples

        if self.ui.solverComboBox.currentText() == 'Fixed-step':
            solver = 'Euler'
        else:
            solver = 'CVode'

        if self.ui.inputCheckBox.isChecked():

            input_variables = []
            for variable in self.modelDescription.modelVariables:
                if variable.causality == 'input':
                    input_variables.append(variable.name)
            try:
                from fmpy.util import read_csv
                filename = self.ui.inputFilenameLineEdit.text()
                input = read_csv(filename, variable_names=input_variables)
            except Exception as e:
                self.log.log(
                    'error',
                    "Failed to load input from '%s'. %s" % (filename, e))
                return
        else:
            input = None

        output = []
        for variable in self.modelDescription.modelVariables:
            output.append(variable.name)

        self.simulationThread = SimulationThread(
            filename=self.filename,
            stopTime=stop_time,
            solver=solver,
            stepSize=step_size,
            relativeTolerance=relative_tolerance,
            outputInterval=output_interval,
            startValues=self.startValues,
            input=input,
            output=output)

        self.ui.actionSimulate.setIcon(QIcon(':/icons/stop.png'))
        self.ui.actionSimulate.setToolTip("Stop simulation")
        self.ui.actionSimulate.triggered.disconnect(self.startSimulation)
        self.ui.actionSimulate.triggered.connect(self.simulationThread.stop)

        self.simulationProgressBar.setVisible(True)

        self.simulationThread.messageChanged.connect(self.log.log)
        self.simulationThread.progressChanged.connect(
            self.simulationProgressBar.setValue)
        self.simulationThread.finished.connect(self.simulationFinished)

        if self.ui.clearLogOnStartButton.isChecked():
            self.log.clear()

        self.setCurrentPage(self.ui.resultPage)

        self.simulationThread.start()
        self.plotUpdateTimer.start(100)

        self.updatePlotLayout()