The installation contains multiple executables. These are listed and explained in the following table. In general, the suffix “_d” denotes debug versions.
||Running simulation with visualization disabled|
||Running simulation with visualization disabled, under soft real-time constraints|
||Running simulation with visualization enabled|
||Running simulation with visualization disabled, under soft real-time constraints|
The FhSim executables takes the following options:
||Produce help message|
||The model description file|
||Create the output file name based on the name of the inputfile||0|
||The results file||modeloutput.csv|
||The log file||logoutput.txt|
||The verbosity of logging to the console [0-4]||2|
||The verbosity of logging to the log file [0-4]||2|
||Run in stim-supported mode?||0|
This information can be obtained by running one of the executables with no argument or with
When running FhSim on Windows, either use the directory containing FhSim as working directory, or add this directory to the PATH.
When running FhSim on linux, make sure that
LD_LIBRARY_PATH contains the directory where the FhSim dependencies are located.
If the simulation is run with visualization enabled, press
<Esc> to abort.
If the simulation is run without visualization, press
The first time a program is run with visualization, an OGRE
dialog may pop up, where you can set your preferred view
settings. It is recommended to select the OpenGL Rendering Subsystem.
If you are likely to do some debugging, it is recommended to turn full screen
off. If you want to change the settings later, you can either edit
ogre.cfg in the resources subdirectory (located in the
same directory as the FhSim executables), or you can delete this file to trigger
the dialog box on the next run.
An Input file is used to configure the simulation in FhSim and is written in extensible markup language (XML). The FhSim input files specify:
An input file is an XML file that says which objects are in the simulation and how they are connected. It also specifies the initial states of the simobjects and sets the parameters of the simulation. It contains a number of mandatory sections, and we will describe each of these in turn.
Note that the whole file should be surrounded by a
tag, so it will look something like this:
<Contents> <OBJECTS> ... </OBJECTS> <INTERCONNECTIONS> ... </INTERCONNECTIONS> ... </Contents>
Remember to save the file with a
.xml extension. For the
remainder of this chapter we will assume that the XML file is
MySystem.xml. Whenever you see
<input directory> in a path, you should
replace it with the full name of the directory in which the file
The input file is divided into different sections, and each has their own specific purpose.
OBJECTS specifies the simulation objects that are part of the
simulation. The SimObjects are usually are compiled into separate shared libraries
dll's on windows), and they are defined by the location and name of the library file,
as well as the type name of the individual object. The parameters are also given for each
Each SimObject is specified by a
<Lib /> tag with the following attributes
The parameters which are specific to a type of SimObject should
normally be described in the documentation for that SimObject.
The names and types must match the implementation. If a SimObject
has a numeric parameter called Mass, for instance, then
is valid whereas
Mass123="abc" is not. The type is actually not
checked though, so
Mass="abc" wouldn’t raise any errors, but
would look quite funny in the simulation. Parameters which have a
default value can be omitted.
The TutorialLib library has a SimObject type called Mass, which
describes a mass with three degrees of freedom. It has the
parameters Mass, Radius and Color. To add such an object to the
simulation, place the following inside the `
<Lib LibName="TutorialLib" SimObject="Mass" Name="mass" Mass="2000" Radius="0.70" Color="0.1, 0.3, 0.9" />
It is important to note that the version of the library must match that of the rest of the API. This means that if FhSim is compiled against dynamic standard libraries, and with visualization, then this must be the case also for the SimObject libraries. To simplify this, the recommended naming convention of the SimObject libraries are to use the following suffices to distinguish between libraries of different linking:
Vis” / “”
_d” / “”
The name of a library may then be assembled as:
LibName<Visualization suffix><Debug suffix>.
One library on Windows may therefore have the following names:
INTERCONNECTIONS specify how the SimObjects are connected. This
is done according to simObject names, port tags and constants. Simobjects have a number
of input and output ports. All input ports must be connected to an output port, but output ports
may be left unconnected. Connections are described through
attributes of a
<Connection> tag, with the following syntax:
<Connection someObject.SomeInport="anotherObject.SomeOutport" ... />
<INTERCONNECTIONS> section can only contain a
<Connection> tag, and this tag must therefore describe all
connections. For examples, see \ref sec_new_simobject_examples.
The names and possible values of a simobject’s states should be specified in the simobject’s documentation.
If the simobject named cable has input ports named PositionA and PositionB, then these can be connected to the Position output port of the simobjects named mass1 and a fixed position like this:
<Connection cable.PositionA="mass1.Position" cable.PositionB="0,0,0" />
The first case connects the input port
PositionA of the SimObject
cable to the
Position of the SimObject
mass1. The second sets the input port
cable equal to the vector
[0 0 0]. The names of the simObjects are defined in
OBJECTS section of the input file, while the tag names are set in the definition of the
SimObjects (in the C++ source code).
The InitialCondition subsection specifies the initial states of the
simObjects. It contains a
<InitialCondition> tag in which the initial conditions of
all objects in the system are specified with the following syntax
<InitialCondition someObject.SomeState="some value" ... />
The initialization is done using the simObject names and the state tag names:
MassOne.Pos="10.0, 0.0, 0.0"
The states which are not initialized, are initially set to zero. There may, however be provided methods in the individual SimObject which sets the initial conditions, either based on the input parameters or input ports. A typical example would be a cable object, which could use positions of the ends to set the initial positions of the nodes in between.
If the mass object has states called Position and Velocity, which are both 3-vectors, its initial conditions may be specified like this:
<InitialCondition mass.Position="-13,2,-5" mass.Velocity="0,0,0" />
The INTEGRATION section contains options that influence how the simulation is run, i.e. which simulation method is used, the time steps etc. The Engine subsection sets the integrator options, as for example
The simulation options decides how the integrator performs. The different options are described in the table below:
||2||0 = Forward Euler.
2 = Runge Kutta 45.
||T0, OutputSpec, T||Defines the start time, the times for outputs and the stop time. If the stop time is given as Inf, it is interpreted as infinite. Note that logging is only done if LogStates is 1 and/or FileOutput is set. Examples are shown below.|
|T||Simulation starting at time 0 (default), no output(default) and T is the stop time.|
|T0,T||Simulation starting at time T0, no output(default) and T is the stop time.|
|T0,To1,T||Simulation starting at time T0, output at t = T01 if activated, the stop time is T.|
|T0, To1,,,ToN, T||Simulation starting at time T0, output at t = To1,,,ToN if activated, the stop time is T.|
|T0, To1:T02, T||Simulation starting at time T0, output at every integration step between t = T01 and To2 if activated, the stop time is T.|
|T0, To1:dT:T02, T||Simulation starting at time T0, output at between t = T01 and To2 with dT interval if logging is activated, the stop time is T.|
||1||Bool (0 or 1). Should the output be logged internally by CFhIntegrator? This is not applicable if the simulation is run by the standard FhSim or FhVis executables.
Set to 1 if logging is wanted.
|Variable step size if 0.
Fixed step size if larger than 0.
||0.1||The maximum allowed step size (for variable step size only).|
||0.1||The minimum allowed step size (for variable step size only). An error will be given if the system can not be solved within error tolerances without using a smaller step size.|
||1e-6||The maximum allowed absolute derivative error (for variable step size only).|
||1e-6||The maximum allowed derivative error relative to the states (for variable step size only).|
| , where = error to compare to allowed tolerance
= the absolute tolerance
= the relative tolerance
= the estimated error in the derivative for state .
||“OBJECT_SET:DATASTREAM_SET”||The OBJECT_SET string defines a set of simombjects from which some kind of outputstream should be logged to file.
The DATASTREAM_SET string defines which streams should be logged from the aforementioned simobjects.
Logging will take place at timesteps defined in the TOutput property
|“objects:all”||Write all ports and states of all simObjects to result file.|
|“objects:ports”||Write the output ports of all simObjects to result file.|
|“objects.Mass:states”||Write the states of all Mass simObjects to result file.|
|“object.spring1:port.ForceA”||Write the ForceA output port of spring1 to result file.|
|“union(object.spring1:ports, objects.Mass:states)”||Write the ports of spring1 AND the states of all Mass objects to result file.|
|“minus(objects:all, union(objects.Mass:ports, objects.Cable:states, object.spring1:ForceB))”||Write everything EXCEPT ports from Mass objects, states from Cable objects and ForceB from spring1.|
|””||Empty string. No output to file.|
||“initialstates.bin”||A binary file containing the initial states.|
||“initialstates.bin”||A binary file to write all final states to. This can be used for continuing the simulation from an earlier state.|
This input file models a mass hanging from a linear spring, which again is hanging from a fixed point.
<Contents> <OBJECTS> <Lib LibName="FhSimBaseLib" SimObject="Body/Mass" Name="mass" Mass="1" Material="Simple/Black" Scale="1"/> <Lib LibName="FhSimBaseLib" SimObject="Cable/LinearSpring" Name="spring" Stiffness="0.10" RelaxedLength="2.5"/> </OBJECTS> <INTERCONNECTIONS> <Connection mass.Force="spring.ForceA" spring.PosA="mass.Pos" spring.PosB="0,0,0" /> </INTERCONNECTIONS> <INITIALIZATION> <InitialCondition mass.Pos="0, 2, 0" mass.Vel="0, 0, 0" /> </INITIALIZATION> <INTEGRATION> <Engine IntegratorMethod="2" TOutput=" 0.0, 10000000 " LogStates = "0" FileOutput = "objects:ports" stepsize ="0.00003" HMax="100" HMin="0.000001" AbsTol="1e-7" RelTol="1e-7" UseRSSNormInsteadOfInfNorm="0" /> </INTEGRATION> </Contents>
This input file models a mass hanging from a cable, which again is hanging from another mass, which is connected to a spring. It uses the TutorialLib library.
<Contents> <OBJECTS> <External Name="ExtObj" outputPortNames="ExtPort" Initial_ExtPort="-13,0,-7" inputPortNames="" Size_asdfgh="" /> <Lib LibName="TutorialLib" SimObject="Mass" Name="mass1" Mass="2.2" Radius="0.20" Color="0.1, 0.9, 0.3" /> <Lib LibName="TutorialLib" SimObject="MassPointCable" Name="cable1" numElements ="49" elementStiffness="100000.0" elementBendingStiffness="10.0" elementMass="0.2" elementLength="0.2" elementDamping="0.16" /> <Lib LibName="TutorialLib" SimObject="Mass" Name="mass" Mass="2000" Radius="0.70" Material="DiffuseSpecular" Color="0.9, 0.1, 0.7" /> <Lib LibName="TutorialLib" SimObject="Spring" Name="spring" Stiffness="18000.0" Length="2.5" /> <Lib LibName="TutorialLib" SimObject="Sum" Name="sum" numInput="2" numComponent="3" /> </OBJECTS> <INTERCONNECTIONS> <Connection mass1.Force="cable1.ForceA" cable1.PositionA="mass1.Position" cable1.PositionB="mass.Position" cable1.VelocityA="mass1.Velocity" cable1.VelocityB="mass.Velocity" spring.PositionB="ExtObj.ExtPort" spring.PositionA="mass.Position" sum.component0_input="spring.ForceA" sum.component1_input="cable1.ForceB" mass.Force="sum.sumPort" /> </INTERCONNECTIONS> <INITIALIZATION> <InitialCondition mass1.Position="-13.0, 2, 5.0" mass1.Velocity="0.0, 1, 0.0" mass.Position="-13,2,-5" mass.Velocity="0,0,0" /> </INITIALIZATION> <INTEGRATION> <Engine IntegratorMethod="2" TOutput="0.0, Inf" LogStates = "0" stepsize ="0.0003" HMax="100" HMin="0.000001" AbsTol="1e-7" RelTol="1e-7" UseRSSNormInsteadOfInfNorm="0" FileOutput="" /> </INTEGRATION> </Contents>
This is an overview of the keys to use while the simulation is running.
||Moves the camera forward|
||Moves the camera backward|
||Moves the camera left|
||Moves the camera right|
||Moves the camera up|
||Moves the camera down|
||Moves the camera along positive x-axis|
||Moves the camera along negative x-axis|
||Moves the camera along positive y-axis|
||Moves the camera along negative y-axis|
||Moves the camera along positive z-axis|
||Moves the camera along negative z-axis|
||Selects a target to use as a target viewpoint|
||De-selects target to use as a target viewpoint|
||Increase camera speed|
||Decrease camera speed|
||Look to the left|
||Look to the right|
||Toggles mesh or surface view|
||Toggles view of origin axes|
||Decreases the size of the origin axes|
||Increases the size of the origin axes|
||Quits the simulation|
It is also possible to add a SimObject that controls the camera movement by moving it along a spline curve defined by a set of nodes containing (time,x,y,z,roll,pitch,yaw). More than one such SimObject can be defined in an XML file, but do not let the time intervals overlap. Note that the NumNodes attribute must be updated if more nodes are added, or they will be ignored!
The Type attribute is not used yet, but can be used in the future to specify other controls, such as following targets.
<OBJECTS> <Lib LibName="..\dlls\FhSimBase" SimObject = "CameraTrajectoryPlayer" Name = "CTP1" Type = "SplinePosAngle" NumNodes = "11" /> </OBJECTS> <INTERCONNECTIONS> <Connection CTP1.Node1 = " 5, 0, 0, 0, 0, 0, 0" CTP1.Node2 = " 15, -50, 0, 50, 0.1, -0.1, 0.2" CTP1.Node3 = " 30, -100, 0, 80, 0.2, -0.1, 0.2" CTP1.Node4 = " 60, -100, 0, 130, 0, 0, 0.2" CTP1.Node5 = " 250, -100, 0, 130, 0, 0, 0.2" CTP1.Node6 = " 350, -100, 0, 130, 0, 0, 0.2" CTP1.Node7 = " 450, -240, 0, 130, 0, 0, 0.2" CTP1.Node8 = " 600, -240, 0, 130, 0, 0, 0.2" CTP1.Node9 = " 700, 0, 240, 100, 0, -0.2, -1.37" CTP1.Node10 = " 1000, 0, 120, 115, 0, -0.2, -1.37" CTP1.Node11 = " 1500, 0, 110, 114, 0, -0.3, -1.57" /> </INTERCONNECTIONS>
To log information from the simulations to a file, one may either use the built-in functionality of the FhSim core, or use a special SimObject.
To add a SimObject of type TextLogger to the
OBJECTS section of your XML file, e.g.:
<OBJECTS> ... <Lib LibName="..\dlls\oscLib" SimObject="TextLogger" Name="MyLogger" FileName="test1.log" NumInports=1 PortWidth=3 SamplingInterval=1 /> ... </OBJECTS>
Then, connect the input port(s) in the
of your XML file, e.g.:
<INTERCONNECTIONS> ... MyLogger.In1="SpringThree.ForceB" ... </INTERCONNECTIONS>
Add the following SimObject to your XML file:
<Lib LibName = "..\dlls\FhSimBase" Simobject = "CameraShot" Time = "15" Name = "Camera1" FrameRate = "6" Filename = "shot.jpg" />
and run FhSim. If no extension to the filename is specified,
.jpg will be added automatically by fhSim. If desired, other
formats may be specified, such as
Add the following SimObject to your XML file and run FhSim. This
will create a number of image files with file extension
<Lib LibName = "..\dlls\FhSimBase" Simobject = "CameraShot" Time = "15" Name = "Camera1" Video = "1" Stop = "100" Filename = "video1.tif" Framerate = "24" Refinement = "1" />
Ensure that your visualization frame-rate is high enough (24fps is recommended), and that your maximum time-step is small enough (0.0045s or smaller is recommended).
ffmpeg -i img%d.png -r 30 -c:v libx264 -x264opts crf=20 video.avi
The options of the
H.264 encoder is written in a colon
separated list after the tag
crf option controls quality.
This is to be set to a number from 1 (best quality and largest file) and up.
20-30 will typically give small files with sufficient quality.
good control of the quality, but no control of the file size. If predictable
file size is important, one may use the ‘bit-rate’ option instead, with the
added option of two-pass encoding.
Further information on h264 encoder options.
While h264 encoding gives the best quality for a given file size, not all players supports this codec. Most notably is the embedded player in Microsoft Powerpoint. Office can not play h264 video unless the codec is specifically installed, for instance the k-lite codec pack.
To generate a powerpoint compatible file use the following command:
ffmpeg -i img%d.png -r 30 -b:v 4096k video.avi
Video quality is controlled with the
-b:v tag, currently set to 4096 kbps.