Source code for pyfmi.examples.fmi_bouncing_ball_native

#!/usr/bin/env python 
# -*- coding: utf-8 -*-

# Copyright (C) 2014 Modelon AB
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os as O

import pylab as P
import numpy as N

from pyfmi import load_fmu

curr_dir = O.path.dirname(O.path.abspath(__file__));
path_to_fmus = O.path.join(curr_dir, 'files', 'FMUs')
path_to_fmus_me1 = O.path.join(path_to_fmus,"ME1.0")
path_to_fmus_cs1 = O.path.join(path_to_fmus,"CS1.0")

[docs]def run_demo(with_plots=True): """ This example shows how to use the raw (JModelica.org) FMI interface for simulation of an FMU. FMU = bouncingBall.fmu (Generated using Qtronic FMU SDK (http://www.qtronic.de/en/fmusdk.html) ) This example is written similair to the example in the documentation of the 'Functional Mock-up Interface for Model Exchange' version 1.0 (http://www.functional-mockup-interface.org/) """ #Load the FMU by specifying the fmu and the directory bouncing_fmu = load_fmu('bouncingBall.fmu',path_to_fmus_me1) Tstart = 0.5 #The start time. Tend = 3.0 #The final simulation time. bouncing_fmu.time = Tstart #Set the start time before the initialization. #Initialize the model. Also sets all the start attributes defined in the # XML file. bouncing_fmu.initialize() #Get Continuous States x = bouncing_fmu.continuous_states #Get the Nominal Values x_nominal = bouncing_fmu.nominal_continuous_states #Get the Event Indicators event_ind = bouncing_fmu.get_event_indicators() #For retrieving the solutions use, #bouncing_fmu.get_real,get_integer,get_boolean,get_string (valueref) #Values for the solution #Retrieve the valureferences for the values 'h' and 'v' vref = [bouncing_fmu.get_variable_valueref('h')] + [bouncing_fmu.get_variable_valueref('v')] t_sol = [Tstart] sol = [bouncing_fmu.get_real(vref)] #Main integration loop. time = Tstart Tnext = Tend #Used for time events dt = 0.01 #Step-size while time < Tend and not bouncing_fmu.get_event_info().terminateSimulation: #Compute the derivative dx = bouncing_fmu.get_derivatives() #Advance h = min(dt, Tnext-time) time = time + h #Set the time bouncing_fmu.time = time #Set the inputs at the current time (if any) #bouncing_fmu.set_real,set_integer,set_boolean,set_string (valueref, values) #Set the states at t = time (Perform the step) x = x + h*dx bouncing_fmu.continuous_states = x #Get the event indicators at t = time event_ind_new = bouncing_fmu.get_event_indicators() #Inform the model about an accepted step and check for step events step_event = bouncing_fmu.completed_integrator_step() #Check for time and state events time_event = abs(time-Tnext) <= 1.e-10 state_event = True if True in ((event_ind_new>0.0) != (event_ind>0.0)) else False #Event handling if step_event or time_event or state_event: eInfo = bouncing_fmu.get_event_info() eInfo.iterationConverged = False #Event iteration while eInfo.iterationConverged == False: bouncing_fmu.event_update(intermediateResult=True) #Stops after each event iteration eInfo = bouncing_fmu.get_event_info() #Retrieve solutions (if needed) if eInfo.iterationConverged == False: #bouncing_fmu.get_real, get_integer, get_boolean, # get_string(valueref) pass #Check if the event affected the state values and if so sets them if eInfo.stateValuesChanged: x = bouncing_fmu.continuous_states #Get new nominal values. if eInfo.stateValueReferencesChanged: atol = 0.01*rtol*bouncing_fmu.nominal_continuous_states #Check for new time event if eInfo.upcomingTimeEvent: Tnext = min(eInfo.nextEventTime, Tend) else: Tnext = Tend event_ind = event_ind_new #Retrieve solutions at t=time for outputs #bouncing_fmu.get_real,get_integer,get_boolean,get_string (valueref) t_sol += [time] sol += [bouncing_fmu.get_real(vref)] #Plot the solution if with_plots: #Plot the height P.figure(1) P.plot(t_sol,N.array(sol)[:,0]) P.title(bouncing_fmu.get_name()) P.ylabel('Height (m)') P.xlabel('Time (s)') #Plot the velocity P.figure(2) P.plot(t_sol,N.array(sol)[:,1]) P.title(bouncing_fmu.get_name()) P.ylabel('Velocity (m/s)') P.xlabel('Time (s)') P.show()
if __name__ == "__main__": run_demo()