Package kenozooid :: Module simulation

Source Code for Module kenozooid.simulation

  1  # 
  2  # Kenozooid - dive planning and analysis toolbox. 
  3  # 
  4  # Copyright (C) 2009-2019 by Artur Wroblewski <wrobell@riseup.net> 
  5  # 
  6  # This program is free software: you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation, either version 3 of the License, or 
  9  # (at your option) any later version. 
 10  # 
 11  # This program is distributed in the hope that it will be useful, 
 12  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  # GNU General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 18  # 
 19   
 20  """ 
 21  Dive simulation routines. 
 22  """ 
 23   
 24  import time 
 25   
26 -def parse(spec):
27 """ 28 Parse dive plan specification. 29 30 Dive plan specification string is a space separated list of dive run 31 time and depth values. For example dive plan 32 33 | RT[min] | Depth[m] | 34 | 1:00 | 10 | 35 | 12:20 | 21 | 36 | 18:30 | 21 | 37 | 40:00 | 5 | 38 | 43:00 | 5 | 39 | 45:00 | 0 | 40 41 is represented by string as follows:: 42 43 1:00,10 12:20,21 18:30,21 40:00,5 43:00,5 45:00,0 44 45 which can be described as 46 47 Run time can be specified in 48 49 - seconds, i.e. 15, 20, 3600 50 - minutes, i.e. 12:20, 14:00, 67:13 51 52 Depth is always specified in meters. 53 54 Dive plan specification is returned as iterator of runtime and depth 55 pairs is returned. Returned runtime is always in seconds since start 56 of a dive. Depth is specified in meters. 57 58 :Parameters: 59 spec 60 Dive plan specification string. 61 """ 62 for chunk in spec.split(): 63 try: 64 t, d = chunk.split(',') 65 if ':' in t: 66 m, s = map(int, t.split(':')) 67 s = min(s, 59) 68 t = m * 60 + s 69 else: 70 t = int(t.strip()) 71 except: 72 raise ValueError('Invalid runtime specification for {}' 73 .format(chunk)) 74 75 try: 76 d = int(d) 77 except: 78 raise ValueError('Invalid depth specification for {}' 79 .format(chunk)) 80 81 yield t, d
82 83
84 -def interpolate(spec):
85 """ 86 Interpolate dive plan times and depths. 87 88 :Parameters: 89 spec 90 Dive plan specification (as returned by ``parse`` function). 91 92 .. seealso:: 93 ``parse`` 94 """ 95 ptime = 0 96 pdepth = 0 97 yield ptime, pdepth 98 for time, depth in spec: 99 count = time - ptime # interpolation amount 100 ddelta = depth - pdepth # depth delta 101 value = abs(ddelta) # value to interpolate 102 103 if value != 0 and count !=0: 104 d1 = 1 105 d2 = float(ddelta) / count 106 # time or depth can be interpolated 107 if value <= count: 108 value, count = count, value 109 d1 = abs(1 / d2) 110 if d2 > 0: 111 d2 = 1 112 else: 113 d2 = -1 114 115 for i in range(1, count): 116 yield int(ptime + d1 * i), int(pdepth + d2 * i) 117 118 119 yield time, depth 120 121 ptime = time 122 pdepth = depth
123 124
125 -def simulate(simulator, spec, start=True, stop=True):
126 """ 127 Simulate dive with specified simulator and dive specification. 128 129 :Parameters: 130 simulator 131 Device driver simulator implementation. 132 spec 133 Dive plan specification. 134 start 135 If `False` then simulation is assumed to be started. 136 stop 137 If `False` then simulation won't be stopped. 138 """ 139 if start: 140 simulator.start() 141 try: 142 # start simulation 143 pt, d, *_ = next(spec) 144 simulator.depth(d) 145 146 for t, d, *_ in spec: 147 time.sleep(t - pt) 148 simulator.depth(d) 149 pt = t 150 151 finally: 152 if stop: 153 simulator.stop()
154 155 # vim: sw=4:et:ai 156