def __init__(self, name, sim, G, head='BC', nCranes=2, startPos=[12.5, -4], bundler=False, twigCrack=False): print "head:", head, "cranes:", nCranes, "bundler:", bundler, "twigcracker:", twigCrack self.driver=Operator(sim,preemptable=1) #add driver sim.activate(self.driver, self.driver.work()) Machine.__init__(self, name, sim, G=G, driver=self.driver, mass=21000) s=self.G.simParam self.velocities={'machine': s['velocityOfMachine'],#1 'crane angular': s['angularVelocityOfCrane'],#0.35 'crane radial': s['radialVelocityOfCrane']}#2.5 #radians/sec,m/s self.color='#CD0000' self.moveEvent=SimEvent(name='machine moves', sim=self.sim) #signals BEFORE movement self.movedEvent=SimEvent(name='machine moves', sim=self.sim) #signals AFTER movement self.times={'crane const':s['moveCraneConst'],#1.5, 'move const':s['moveConst'],#5, 'switchFocus': s['switchFocusTime']}#3 #change before activating. May be changed from craneHead constructor self.craneMaxL=s['maxCraneLength']#11 self.craneMinL=s['minCraneLength']#3 self.automaticMove=s['moveMachine']#False self.hasBundler=bundler self.prio=0 self.length=6.939 self.width=2.720 self.pos=startPos self.trees=[] self.mainRoadTrees=[] self.corridorTrees=[] self.heads={} #dictionary with keys 'left', 'right' self.nCranes=nCranes #Here is the bundler initiation if bundler == True: self.bundler=Bundler(sim=self.sim, driver=self.driver, machine=self) self.sim.activate(self.bundler,self.bundler.run()) #Here is the head initiation if head=='BC': for i in range(nCranes): h=BCHead(sim=self.sim, driver=self.driver, machine=self, twigCrack=twigCrack) #adds to above list. elif head=='convAcc': for i in range(nCranes): h=ConventionalHeadAcc(sim=self.sim, driver=self.driver, machine=self, twigCrack=twigCrack) #adds to above list. else: raise Exception('ThinningMachine did not recognize head %s'%str(head)) for h in self.heads.values(): self.sim.activate(h, h.run()) self.treeMoni=Monitor(name='trees harvested') self.treeMoni.observe(len(self.trees), self.sim.now()) self.roadList=[] #simply a list of roads. self.roads={} #a dictionary, more sophisticated structure with simplifies finding the road for a spec. pos. self.setUpCorridors()
def __init__(self, name, sim, G): Machine.__init__(self, name, sim, G=G, driver=None, mass=10000) if not G.roadNet: raise Exception('Forwarder needs a road net to work on') self.roadNet=G.roadNet #networkX graph class self.treeMoni=Monitor(name="Trees in cargo") self.totalTreeMoni=Monitor(name="Trees picked up") self.distTot=0 #faster than to inspect monitor every time. self.distMoni=Monitor(name="distance traveled") self.origin=G.roadNet.graph['origin'] #observe, this is and has to be a tuple. self.times={'pickUpTrees':8, 'dumpTrees': 14} self.velocities= {'machine':1,'reverse': 0.5, 'crane':1} #m/s not taken from reality self.setPos(self.origin) self.nextPos=None #only none if at origin self.pickup_road=None self.trees=0 self.treeWeight=0 self.treeVolume=0 self.capacity=12000 #kg.. don't care about volume now.. self.grappleCapacity=0.35 #radius of cylinder that can be gripped self.craneMax=7.8 self.reset()
def __init__(self, name, sim, G, mtype='1a2h', craneLim=None): if not craneLim: craneLim=[4.0,9.0] Machine.__init__(self, name, sim, G=G, mass=21000) self.driver=Operator(sim=self.sim, delay=10000) #does not go on breaks.. self.sim.activate(self.driver, self.driver.work()) return None self.type=mtype if self.type=='1a2h' or self.type=='2a4h': self.headType='Mplanter' else: self.headType='Bracke' self.pos=[0,0] self.craneMaxL=G.craneLim[1] self.craneMinL=G.craneLim[0] if self.craneMaxL <= self.craneMinL: raise Exception('crane maximum is smaller than crane minimum...') self.pos[0]=random.uniform(G.terrain.xlim[0]+self.craneMaxL, G.terrain.xlim[1]- self.craneMaxL) self.pos[1]=random.uniform(G.terrain.ylim[0]+self.craneMaxL, G.terrain.ylim[1]- self.craneMaxL) if self.G.PMattach: self.craneIntersect=self.G.PMattach else: self.craneIntersect=3.0 if self.craneMinL<=self.craneIntersect: self.craneMinL=self.craneIntersect-0.01 # of course.. self.visual={'upperStructLength':4.3, 'upperStructWidth':2.540 ,'trackWidth':0.6,'trackLength':4.460 } po1=[self.visual['upperStructWidth']/2.+(2.990-2.540)/4., 0] po2=[-self.visual['upperStructWidth']/2.-(2.990-2.540)/4., 0] self.visual['trackCntrPosLoc']=[po1,po2] #just for plotting.. self.workingArea=pow(self.craneMaxL,2)*pi/2.-pow(self.craneMinL,2)*pi/2. if self.G.PMstockingRate: self.stockingRate=self.G.PMstockingRate else: self.stockingRate=2000 # plants/ha self.plantMinDist=G.plantMinDist self.dibbleDepth=0.1 self.nSeedlingsPWArea=floor(self.stockingRate/10000.*self.workingArea) print "sPerWorkarea:", self.nSeedlingsPWArea, "cranemax:", self.craneMaxL, "cranemin:",self.craneMinL, "attach:", self.craneIntersect #self.direction=random.uniform(0,2*pi) self.direction=0 self.times={'diggTime': 3, 'heapTime': 2,'moundAndHeapTime': 5, 'dibbleDownTime': 1, 'relSeedlingTime': 1, 'dibbleUpTime':1, 'haltTime': 3, 'searchTime': 0, 'switchFocus':0} self.timeConsumption={'diggTime': 0, 'heapTime': 0,'moundAndHeapTime': 0, 'dibbleDownTime': 0, 'relSeedlingTime': 0, 'haltTime': 0, 'searchTime': 0, 'switchFocus':0, 'machineMovement':0} self.type=mtype self.pDevs=[] self.treesPlanted=[] self.automatic=G.automatic self.velocities={'machine': 0.5, 'angMachine':11.8*2*pi/60., 'angCranes': 15*pi/180, 'radial': 1.6} #radians/sec and m/s self.timeConstants={'machine': 5, 'maincrane':1.5, 'subcrane':0.1} #time taken to initiate movements. if self.G.PMradialCraneSpeed: self.velocities['radial']=self.G.PMradialCraneSpeed self.angleLim=self.G.PMangleLim #angle limit between the two arms/planting devices. self.treeMoni=Monitor(name="Trees planted") self.leftAngleMoni=Monitor(name="angle for left crane") self.rightAngleMoni=Monitor(name="angle for right crane") self.treeMoni.observe(len(self.treesPlanted), self.sim.now()) p1=PlantingDevice('rightDevice', sim=self.sim, belongToMachine=self, G=self.G) self.sim.activate(p1,p1.run()) self.pDevs.append(p1) if mtype[0:2]=='2a': #add another one self.times['switchFocus']=2 self.timeConstants['machine']*=1.5 #longer time for 2a self.velocities['machine']*=0.75 p2=PlantingDevice('leftDevice', sim=self.sim, belongToMachine=self, G=self.G) self.sim.activate(p2,p2.run()) self.pDevs.append(p2) if self.exceedsAngleLim(self.pDevs[0], self.pDevs[0].pos, self.pDevs[1]): #angle is too big, needs to adjust. it=0 while self.exceedsAngleLim(self.pDevs[0], self.pDevs[0].pos, self.pDevs[1]): newcyl=[self.pDevs[0].posCyl[0], self.pDevs[0].posCyl[1]+pi/50.] print self.pDevs[0].posCyl, newcyl newpos=getCartesian(newcyl, origin=self.pos, direction=self.direction) if collide(self.pDevs[0], self.pDevs[1], o1pos=newpos) or it>20: raise Exception('exceeds initially and cannot adjust.', it, newcyl) self.pDevs[0].setPos(newpos) self.mass+=4000. #the other planting head has a mass of 4 tons. self.inPlaceEvent=SimEvent('machine has moved in place', sim=self.sim) #event fired when machine has moved self.calcStumpsInWA() #updates some statistics if self.headType=='Mplanter': self.times['searchTime']=0.1*self.sim.stats['stumps in WA'] #specifics for this head..0 otherwise elif self.headType=='Bracke': pass else: raise Exception('could not identify head type') #safety first..
def __init__(self, name, sim, G, mtype='2h', craneLim=None): if not mtype in self.allowedTypes: raise Exception('Machine type %s no allowed'%str(mtype)) if not craneLim: craneLim=[4.0,9.0] Machine.__init__(self, name, sim, G=G, mass=21000) self.driver=Operator(sim=self.sim, delay=10000) #does not go on breaks.. self.sim.activate(self.driver, self.driver.work()) self.type=mtype if '2h' in self.type: self.headType='Mplanter' elif '3h' in self.type or '4h' in self.type: self.headType='MultiHead' #several heads, don't know how many yet. else: self.headType='Bracke' self.times={'heapTime': 2,'dibbleDownTime': 1, 'relSeedlingTime': 1, 'dibbleUpTime':1, 'haltTime': 1, 'searchTime': 0, 'switchFocus':0, 'invertTime':G.simParam['tCWhenInvKO'], 'invert':None} #all in seconds, invert is determined later self.timeConsumption={'heapTime': 0,'moundAndHeapTime': 0, 'dibbleDownTime': 0, 'relSeedlingTime': 0, 'haltTime': 0, 'searchTime': 0, 'switchFocus':0, 'machineMovement':0} #new function for digTime, see plant method. self.pos=[0,0] self.craneMaxL=G.craneLim[1] self.craneMinL=G.craneLim[0] if self.craneMaxL <= self.craneMinL: raise Exception('crane maximum is smaller than crane minimum...') self.pos[0]=random.uniform(G.terrain.xlim[0]+self.craneMaxL, G.terrain.xlim[1]- self.craneMaxL) self.pos[1]=random.uniform(G.terrain.ylim[0]+self.craneMaxL, G.terrain.ylim[1]- self.craneMaxL) if self.G.PMattach: self.craneIntersect=self.G.PMattach else: self.craneIntersect=3.0 if self.craneMinL<=self.craneIntersect: self.craneMinL=self.craneIntersect-0.01 # of course.. self.visual={'upperStructLength':4.3, 'upperStructWidth':2.540 ,'trackWidth':0.6,'trackLength':4.460 } po1=[self.visual['upperStructWidth']/2.+(2.990-2.540)/4., 0] po2=[-self.visual['upperStructWidth']/2.-(2.990-2.540)/4., 0] self.visual['trackCntrPosLoc']=[po1,po2] #just for plotting.. self.workingArea=pow(self.craneMaxL,2)*pi/2.-pow(self.craneMinL,2)*pi/2. self.stockingRate=self.G.simParam['TSR'] self.plantMinDist=G.simParam['dibbleDist'] self.dibbleDepth=0.1 self.moundingFailureProb=G.simParam['moundFailureProb']=0.05 self.inverting=G.simParam['inverting'] if self.inverting: assert G.simParam['ExcavatorInverting']!=G.simParam['KOInverting'] #can't use both if G.simParam['KOInverting']: self.invertingMethod='KO' self.invertFailureProb=G.simParam['invertKOFailureProb'] else: self.invertingMethod='Excavator' self.invertFailureProb=G.simParam['invertExcFailureProb'] if 'ObAv' in self.type: self.rootDegreesOK=self.G.simParam['angRootObAv'] if self.G.simParam['wMB']==0.6: self.immobilePercent=self.G.simParam['vertOccStoneObAv60'] elif self.G.simParam['wMB']==0.5: self.immobilePercent=self.G.simParam['vertOccStoneObAv50'] else: self.immobilePercent=self.G.simParam['vertOccStoneObAv40'] else: self.rootDegreesOK=pi/180.0*G.simParam['angRoot'] self.immobilePercent=G.simParam['vertOccStone'] self.nSeedlingsPWArea=max(floor(self.stockingRate/10000.*self.workingArea),1) print "sPerWorkarea:", self.nSeedlingsPWArea, "cranemax:", self.craneMaxL, "cranemin:",self.craneMinL, "attach:", self.craneIntersect self.direction=random.uniform(0,2*pi) self.pDevs=[] self.treesPlanted=[] self.automatic=G.automatic self.velocities={'machine': 0.5, 'angMachine':11.8*2*pi/60., 'angCranes': 15*pi/180, 'radial': 1.6} #radians/sec and m/s self.timeConstants={'machine': 5, 'maincrane':1.5, 'subcrane':0.1} #time taken to initiate movements. if self.G.PMradialCraneSpeed: self.velocities['radial']=self.G.PMradialCraneSpeed self.angleLim=self.G.PMangleLim #angle limit between the two arms/planting devices. self.treeMoni=Monitor(name="Trees planted") self.leftAngleMoni=Monitor(name="angle for left crane") self.rightAngleMoni=Monitor(name="angle for right crane") self.treeMoni.observe(len(self.treesPlanted), self.sim.now()) p1=PlantingDevice('rightDevice', sim=self.sim, belongToMachine=self, G=self.G) self.sim.activate(p1,p1.run()) self.pDevs.append(p1) if '2a' in self.type: #add another one. 1a is default self.times['switchFocus']=2 self.timeConstants['machine']*=1.5 #longer time for 2a self.velocities['machine']*=0.75 #heavier, takes more time to move. Part of BTE model p2=PlantingDevice('leftDevice', sim=self.sim, belongToMachine=self, G=self.G) self.sim.activate(p2,p2.run()) self.pDevs.append(p2) if self.exceedsAngleLim(self.pDevs[0], self.pDevs[0].pos, self.pDevs[1]): #angle is too big, needs to adjust. it=0 while self.exceedsAngleLim(self.pDevs[0], self.pDevs[0].pos, self.pDevs[1]): newcyl=[self.pDevs[0].posCyl[0], self.pDevs[0].posCyl[1]+pi/50.] print self.pDevs[0].posCyl, newcyl newpos=getCartesian(newcyl, origin=self.pos, direction=self.direction) if collide(self.pDevs[0], self.pDevs[1], o1pos=newpos) or it>20: raise Exception('exceeds initially and cannot adjust.', it, newcyl) self.pDevs[0].setPos(newpos) self.mass+=4000. #the other planting head has a mass of 4 tons. self.inPlaceEvent=SimEvent('machine has moved in place', sim=self.sim) #event fired when machine has moved self.calcVisibleObstInWA() #some statistics updates needed if self.headType=='Mplanter' or self.headType=='MultiHead': multiplier=self.G.simParam['multiplierFindMuSite'] self.times['searchTime']=multiplier*self.sim.stats['visible obstacles in WA'] #specifics for this head..0 otherwise elif self.headType!='Bracke': raise Exception('could not identify head type %s'%self.headType) #safety first..