Module shipModels
[hide private]
[frames] | no frames]

Source Code for Module shipModels

  1  ################################################################################## 
  2  # Copyright (c) 2010, 2011, 2012, 2013, Daniel Urieli, Peter Stone 
  3  # University of Texas at Austin 
  4  # All right reserved 
  5  #  
  6  # Based On: 
  7  #  
  8  # Copyright (c) 2000-2003, Jelle Kok, University of Amsterdam 
  9  # All rights reserved. 
 10  #  
 11  # Redistribution and use in source and binary forms, with or without 
 12  # modification, are permitted provided that the following conditions are met: 
 13  #  
 14  # 1. Redistributions of source code must retain the above copyright notice, this 
 15  # list of conditions and the following disclaimer. 
 16  #  
 17  # 2. Redistributions in binary form must reproduce the above copyright notice, 
 18  # this list of conditions and the following disclaimer in the documentation 
 19  # and/or other materials provided with the distribution. 
 20  #  
 21  # 3. Neither the name of the University of Amsterdam nor the names of its 
 22  # contributors may be used to endorse or promote products derived from this 
 23  # software without specific prior written permission. 
 24  #  
 25  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 26  # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 27  # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 28  # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
 29  # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
 30  # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 31  # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 32  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
 33  # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 34  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 35  ################################################################################## 
 36   
 37   
 38   
 39  from math import * 
 40   
 41  from perceptModels import * 
 42   
 43  ############################################################### 
 44  # PerceptionModule - the perception part of the ship 
 45  ############################################################### 
46 -class PerceptionModule:
47 """ 48 Interface for the perception system of a ship. 49 """ 50
51 - def getListOfPercepts(self, fullState):
52 """ 53 An abstract function, that defines an interface for perception. 54 Its input is the full world state, and its output is a list 55 of percepts that the ships senses, based on the current world 56 state. 57 """ 58 abstract
59 60
61 -class CompleteStatePerceptionModule(PerceptionModule):
62 "Percepts the complete state of the world" 63
64 - def getListOfPercepts(self, fullState):
65 res = PerceptList() 66 res.appendPercept(CompleteStatePercept(fullState)) 67 return res
68 69 70 71 ###################################################### 72 # The Ship class - modeling all aspects of a ship 73 ###################################################### 74
75 -class Ship:
76 """ 77 This class describes a general ship. 78 A ship has: 79 - Perception capability 80 - A set of legal actions that can be applied to it, through its interface functions. 81 - An internal state (currently the state of it's actuators) 82 that is controlled through the set of legal actions. 83 - Functions that describes its response to the environment, and depends on its 84 physical properties. 85 86 Any implementation of any of the above part can be plugged-in, allowing 87 to mix different combinations of capabilities into a ship. 88 89 A ship's external state, which is its coordinates, velocity, orientation 90 and so on, is not part of the ship itself, but part of the environment, 91 and is part of the world state. 92 """ 93 # TODO: later abstract a ship to a percetion module, and action module 94 # that define what can the ship percept, and what actions 95 # can be done on it? and also allow to mix those in different ships
96 - def __init__(self, perceptionModule = CompleteStatePerceptionModule(), 97 initialEngineSpeed = 0, 98 initialSteering = 0, 99 maxSpeed = 40, 100 minSpeed = -10, 101 maxSteering = 90, 102 minSteering = -90, 103 mass = 1000, 104 #mass = 100, 105 length = 12):
106 #print 'Creating ship model' 107 self.perception = perceptionModule 108 self.engineSpeed = initialEngineSpeed 109 self.steering = initialSteering 110 self.maxSpeed = maxSpeed 111 self.minSpeed = minSpeed 112 self.maxSteering = maxSteering 113 self.minSteering = minSteering 114 self.mass = mass 115 self.length = length
116
117 - def __str__(self):
118 res = "\nShip:" 119 for member, value in vars(self).items(): 120 res += " " + member + "=" + str(value) 121 return res
122 123 124 ############################################# 125 # Functions supplied for the agent 126 ############################################# 127
128 - def getPercepts(self, fullState):
129 """ 130 We view the ship as receiving a full world state 131 and then "filtering" it to only the percepts it is 132 able to process. Philosophically, we could view 133 the world that way: we are only able to process 134 part of the complete information that surrounds us. 135 """ 136 return self.perception.getListOfPercepts(fullState)
137
138 - def executeAction(self, action):
139 """ 140 Change the internal state of a ship as a result of an action 141 that was chosen by the ship agent. 142 The 'action' argument can be a (possibly empty) composite action, 143 and in general is a list of pairs of the form (methodname, args), 144 such that self.methodname(args) is executed for each pair. 145 """ 146 for a in action.primitiveActions: 147 getattr(self, a.functionName) (*a.args)
148 149 150 ########################################### 151 # Physical actions a ship should provide 152 ########################################### 153
154 - def setSteering(self, steering):
155 if steering < self.minSteering or steering > self.maxSteering: 156 print '-W- steering is out of range, action has no affect' 157 return 158 print '-W- steering is out of range, fix that' 159 self.steering = steering
160 161
162 - def setEngineSpeed(self, speed):
163 if speed < self.minSpeed or speed > self.maxSpeed: 164 print '-W- speed is out of range, action has no affect' 165 return 166 print '-W- speed is out of range, fix that' 167 self.engineSpeed = speed
168
169 - def stop(self):
170 """Stop the ship. 171 This function might need to be changed because it will not always be 172 correct that setting everything to 0 will stop it 173 """ 174 self.setSteering(0) 175 self.setEngineSpeed(0)
176 177 178 ########################################### 179 # Physical response to the environment 180 # (TODO: in the future, extract this part to a seperate class, for example like the perception module) 181 ###########################################
182 - def getForwardForce(self, shipSpeed):
183 """ 184 Computing the forward force applied on the ship based on the engine and the drag forces. 185 """ 186 forwardDragConstant = 100.0 # some proportionality constant 187 # TODO: change engineSpeed 188 engineForce = self.engineSpeed * 50.0 189 # Drag is proportional to speed^2, with direction opposite to the speed 190 dragForce = -shipSpeed * abs(shipSpeed) * forwardDragConstant 191 # print 'forwardForce', engineForce + dragForce, 'engineForce', engineForce, 'forwardDragForce', dragForce, 'shipSpeed', shipSpeed 192 return engineForce + dragForce
193
194 - def getSteeringForce(self, shipSpeed, shipAngularSpeed):
195 """Computing the steering force based on the, the speed, the drag and so on.""" 196 # TODO: fix according to the comment above 197 const = 1.5 198 angularDragConst = 0.5 199 rudderForce = sin(radians(self.steering)) * shipSpeed * const 200 # Drag is proportional to speed^2, with direction opposite to the speed 201 dragForce = -shipAngularSpeed * abs(shipAngularSpeed) * angularDragConst 202 # print 'rudderForce', rudderForce, 'dragForce', dragForce, 'steering', self.steering, 'shipSpeed', shipSpeed, 'shipAngularSpeed', shipAngularSpeed 203 return rudderForce + dragForce
204
205 - def getForwardAccelerationFromForce(self, forwardForce):
206 return forwardForce / self.mass
207
208 - def getAngularAccelerationFromForce(self, steeringForce):
209 """ 210 Assuming mass is spread homogenously. 211 Using formulas from http://rockpile.phys.virginia.edu/arch16.pdf 212 that relates angular acceleration to torque. 213 """ 214 radius = self.length / 2.0 215 return degrees( steeringForce / ( 1 / 12.0 * self.mass * radius) )
216
217 - def getOffsetByEnvConditions(self, windVector, currentVector, orient):
218 """ 219 Compute a ship's response to the environment conditions. 220 221 @type windVector: NumPy vector 222 @param windVector: vector of the wind in the ship's location 223 224 @type currentVector: a numpy vector 225 @param currentVector: vector of the current in the ship's location 226 227 @type orient: float 228 @param orient: The ship's orientation (part of determining the response) 229 230 @rtype: NumPy vector 231 @return: An (x, y) offset of the ship, as a numpy vector 232 """ 233 # TODO: currently we don't use the orient parameter - change that. 234 windConstant = 0.01 235 currentConstant = 0.1 236 return windConstant * windVector + currentConstant * currentVector
237