haml-scais attempts to simplify scais xml generation by extending haml features to add scais module generation.
-
Automatic index generation for topologies
-
Topology module generation with an easy syntax
-
Allow the use of variable and constant in scais xml generation
First you should download the latest haml and haml-scais version.
You can include haml-scais instruction in your haml file just like any code but at generation time you should execute haml-scais command instead of haml.
Create a topology file ‘topo.haml’ and copy the following lines.
# topo.haml !!!XML = topo = Topology.new('TankVolumeAuto').description('Tank Topology for Volume Automatic Protection').name('TopoTankVolumeAuto') do |topo| - topo.add_block do - Fint.new('BF1').times((1..10).to_a).coefs(((1..10).to_a))
Now lets generate the xml
haml-scais topo.haml topo.xml
The resulting xml should be something like this
# topo.xml <?xml version='1.0' encoding='utf-8' ?> <Topology Code="TankVolumeAuto" Description="Tank Topology for Volume Automatic Protection" Name="TopoTankVolumeAuto" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:///home/nico/csn/scais/BABIECA/Schema/Topology.xsd"> <block Code="BF1" FlagActive="1" ModuleType="FINT" Name="BF1"> <index>1</index> <output Code="O0" FlagSave="0"> </output> <constant Code="TIME"> <value>1,2,3,4,5,6,7,8,9,10</value> </constant> <constant Code="COEF"> <value>1,2,3,4,5,6,7,8,9,10</value> </constant> </block> </Topology>
To create a topology use Topology class. As with all haml-scais classes you can set Topology attributes on creation time or set the later. When creating the topology you have to at least specify a code that uniquelly identifies this object. Usually attributes setter apart from usual syntax (setter= value) accepts another one (setter(value)). The second one is chainable, meaning that afterwards you can callother method from this object including setter:
Topology.new('Topo').name('This is my name').description('And my description') # which is equivalent to Topology.new('Topo', :name => 'This is my name', :description => 'And my description')
You can set the following properties of a topology:
-
code
-
name
-
description
The topology class automatically sets the other properties based on your scais install.
Also the topology will add an automatic index to every block added to it.
Topology.new('Topo') do |topo| topo.add_block Fint.new('BF-1') # this block has index 1 topo.add_block Fint.new('BF-2').index(3) # this block has index 3 topo.add_block Fint.new('BF-3') # this block has index 4 end
To add blocks to a topology we use add_block method. This can be called either with a topology block or a ruby block evaluating to a topology block. These three chunks of code are equivalent
topo.add_block Fint.new('BF-2').index(3) topo.add_block do Fint.new('BF-2').index(3) end topo.add_block do fint = Fint.new('BF-2') fint.index(3) # remember that most setter methods in this form return the block end
You can print the topology xml structure using to_xml method
All blocks are subclasses of Block::Base so they all have a similar behaviour.
Common block attributes
-
modes
-
name
-
active (boolean)
-
debug (accepts :info, :debug, :warning, :fatal)
-
code
Setting outputs
block.outputs do output # output with default configuration output.save(true).alias('Output 0') # output saved, with alias 'Output 0' ... end
Setting inputs
# generate blocks fu = Funin.new('B1') ... vm = Vmetodo.new('BVm') ... block = ... # block of some kind # connect block input from fu output block.inputs do input.from('B1.O0') # input as block.output input.from('B1') # if no output given, default is O0 input.from(fu) # if block given, takes O0 from block input.from(fu.output(0)) # also you can give the output directly end # what if we have a vmetodo block? block.inputs do input.from('BVm.YP1') input.from(vm.output(:yp1)) end
To set up funin formula, use the formula chainable method
funin.formula formula_string
Example
funin = Funin.new('B8', :name =>'FUNIN EXP-2', :active => true).debug(:fatal).index(8).modes('B') funin.outputs do output.save(true).alias('ANALYT2') end funin.inputs do input.alias('I0').from('B1').modes('B') end funin.formula "I0+sqrt(2/5)*exp((TAU-TIME)/2)*sin(0.5*(sqrt(5)*(TIME-TAU)*PI)"
To create a fint module you have to set times and coefs. This are chainable methods that accept arrays of values
Example
fint = Fint.new('B1').name('FINT TRIGGER').debug(:info).index(1).modes('ALL') fint.outputs do output.save(true).alias('TRIGGER') end fint.times([-100,0.1,0.1,100]) fint.coefs([0,0,1,1])
Example
c = Convex.new('B9', :name => 'CONVEX LAG-2MODE').active(true).debug(:info).index(9).modes('B') c.outputs do output.save(true).alias('NUM-B') end c.inputs do input.from('B7').modes('B') end c.roots = [-0.5, 0.5] c.vforz = 0
Example
logate = Logate.new('B16').name('MULTIPLEXOR').active(true).debug(:info).index(16).modes('ALL') logate.outputs do output.alias('MULTIPLEXACION').save(true) end logate.inputs do input.alias('I0').from('B1').modes('ALL') end logate.high.from('B14').modes('ALL').alias('IN_HIGH') logate.low.from('B15').modes('ALL').alias('IN_LOW') logate.condition "I0>0" logate.initial_output(0, :alias => 'INITSTATE')
Example
lh = LogateHandler.new('B5').name('LogateModeChange').debug(:info).active(true).index(5).modes('ALL') lh.outputs do output.alias('LOGAT1') end lh.inputs do input.from('B4').alias('I0').modes('ALL') end lh.previous_output :alias => 'PREVOUT' lh.initial_output(0, :alias => 'INITOUT') lh.precision 0.005 lh.condition "(TIME<2.3) and (I0>1)"
Example
topo = Topology.new("OsciladorVanPol", :description => "Diferential Ecuation Resolution", :name => "OsciladorVanPol") do |topo| b1 = Vmetodo.new('B1').name('VMETODO').active(true).debug(:info).modes('ALL') b1.yp1 'y2', :alias => 'yp1', :save => true b1.yp2 '-y1 + cos(1.41 * Vmetodo::TIME)', :alias => 'yp2', :save => true b1.y1 0.01, :alias => :y1, :save => true b1.y2 0.00001, :alias => :y2, :save => true topo.add_block b1 end
Example
b = Files.new('B1').name('FILES Triple BC').active(true).debug(:info).index(1).modes('ALL') b.outputs do output.save(true).alias('BC-1') output.save(true).alias('BC-2') output.save(true).alias('BC-3') end b.file 'path-to-file/data.dat' b.select_for 'O0', :time => 0, :value => 1 b.select_for 'O1', :time => 0, :value => 2 b.select_for 'O2', :time => 3, :value => 4
Example
Acelerator.new('Acc1', :mode => 'PASSIVE').threshold(1).max_iterations(10)
-
Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet
-
Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it
-
Fork the project
-
Start a feature/bugfix branch
-
Commit and push until you are happy with your contribution
-
Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.
-
Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
Copyright © 2011 nico. See LICENSE.txt for further details.