SinGen.rst 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. Sine Generator
  2. ==============
  3. A very simple example usage of the framework is to create a CBD model
  4. that implements the equation :math:`y = sin(t)`, where :math:`t` is
  5. the simulation time and :math:`y` an output signal we're interested in.
  6. Luckily, the standard library provides some functionalities to help us
  7. solve this problem. Let's import three blocks:
  8. .. code-block:: python
  9. from CBD.lib.std import TimeBlock, GenericBlock
  10. The :class:`CBD.lib.std.TimeBlock` will output the current simulation time
  11. every delta timeunits. This block will be used to obtain the :math:`t`
  12. variable. The :class:`CBD.lib.std.GenericBlock` is a generic interface to
  13. Python's :mod:`math` module. We will use this block to implement the sine
  14. function itself.
  15. Next, we need a container to group these blocks in. This is done in the
  16. hierarchical :class:`CBD.CBD.CBD` class. Let's call this "grouping" block
  17. :code:`SinGen` and give it a single output port, named :code:`OUT1`.
  18. .. code-block:: python
  19. from CBD.CBD import CBD
  20. class SinGen(CBD):
  21. def __init__(self, name="SinGen"):
  22. CBD.__init__(self, name, input_ports=[], output_ports=["OUT1"])
  23. # Add the 't' parameter
  24. # Let's call it 'time'
  25. self.addBlock(TimeBlock("time"))
  26. # Add the block that computes the actual sine function
  27. # Let's call it 'sin'
  28. self.addBlock(GenericBlock("sin", block_operator="sin"))
  29. # Connect them together
  30. self.addConnection("time", "sin", output_port_name='OUT1',
  31. input_port_name='IN1')
  32. # Connect the output port
  33. self.addConnection("sin", "OUT1", output_port_name='OUT1')
  34. sinGen = SinGen("SinGen")
  35. Notice how this is semantically equivelent to:
  36. .. code-block:: python
  37. from CBD.CBD import CBD
  38. sinGen = CBD("SinGen", [], ["OUT1"])
  39. # Add the time, just like above
  40. sinGen.addBlock(TimeBlock("time"))
  41. sinGen.addBlock(GenericBlock("sin", block_operator="sin"))
  42. sinGen.addConnection("time", "sin", output_port_name='OUT1',
  43. input_port_name='IN1')
  44. sinGen.addConnection("sin", "OUT1", output_port_name='OUT1')
  45. If we now want to simulate our model for 20 seconds (of simulation-time), we can
  46. simply do:
  47. .. code-block:: python
  48. from CBD.simulator import Simulator
  49. sim = Simulator(sinGen)
  50. # The termination time can be set as argument to the run call
  51. sim.run(20.0)
  52. Next, we would like to obtain the accumulated simulation data on the :code:`OUT1`
  53. output port of the :code:`sinGen` block, which can be plotted against their iteration
  54. (which is equivalent to the time in this case).
  55. .. code-block:: python
  56. data = sinGen.getSignal('OUT1')
  57. x, y = [x for x, _ in data], [y for _, y in data]
  58. .. figure:: ../_figures/sin-disc.png
  59. Now, this is obviously not the sine wave we know and love. This is because our simulator
  60. only computes at 0, 1, 2, 3... seconds, but not in-between. This can be changed by altering
  61. the time delta **before** the start of a simulation:
  62. .. code-block:: python
  63. sinGen.setDeltaT(0.1)
  64. Now, we interpolate the sine-wave every 10th of a second, which looks much better:
  65. .. figure:: ../_figures/sin-cont.png
  66. .. seealso::
  67. :mod:`CBD.lib.std`: The standard set of CBD building blocks that can be used.