Created with
NetLogo version NetLogo 4.0

Running with NetLogoLite.jar version 404.

NetLogo Version: NetLogo 4.0

breed [ whales a_whale ] breed [ boats a_boat ] boats-own [ whale wx wy wh wdx wdy ws gx gy gh max-speed max-turn safe-distance speed accel safe-range ] whales-own [ speed spook-zone ] to startup setup end to setup ca create-whales 1 [ set shape "whale" setxy 0 0 rt random 360 set speed 0 set size 10 set spook-zone 15 set color blue ] create-boats 1 [ set shape "boat" set color yellow set max-speed .2 set max-turn 1 setxy 0 0 rt random 360 jump world-width * .4 rt random 360 set whale one-of whales set safe-distance 30 set safe-range 10 set size 10 set speed 0 set accel .02 pd ] end to go every .01 [ ask whales [ ;; whale meanders... set speed speed + .02 - random-float .04 set speed (min list (max list speed 0 ) .1) let turn 5 * (.2 - speed) rt turn - random-float (turn * 2) jump speed let boat one-of boats if distance boat < spook-zone [ let attack-heading 180 + towards boat let heading-diff subtract-headings attack-heading heading rt .5 * heading-diff ] ;; rarely, whale reverses course if random 20000 < 1 [ rt (165 + random-float 30) ] ] ask boats [ ; 1. calculate goal position and heading ; 2. Set heading as needed ; 3. Move boat. ; Step 1 uses some trigonometry trickery. ;; assumes "whale" is boats-owned, and already set to the whale agent to track ;; assumes "pwx" and "pwy" are boats-owned ;; assumes safe-distance is boats-owned and already set to some number of units set wx [ xcor ] of whale set wy [ ycor ] of whale set wh [ heading ] of whale set wdx [ dx ] of whale set wdy [ dy ] of whale set ws [ speed ] of whale ;; goal point is a point that is a safe-distance away and ;; 90 degrees clockwise from whale heading ;; goal heading is the same as the whale heading ;; trig trick: the point ( xcor + dx ) ( ycor + dy) is 1 unit directly ahead of the agent ;; and (xcor + dy) (ycor - dx) ) is a point 1 unit away and 90 degrees clockwise! ;; if we multiply dx and dy by the safe-distance, we get just the point we need, ;; the goal point. set gx wx + wdy * safe-distance set gy wy - wdx * safe-distance ask patch gx gy [ set pcolor gray ] ;; and the goal heading is the whale heading set gh wh ;; Now, step 2 is the tricky one: ;; 2a. if boat is more than desired maximum distance away from whale, turn boat (at safe turning speed), if needed, toward goal point*, but also tend to keep boat aligned with whale ;; 2b if boat is less than safe distance away, turn boat away from whale, away from whale direction of travel, but toward goal point, if possible (generally, desired avoidence heading will be perpendicular to heading toward whale, direction depends on whale direction and goal direction. ;; 2c. if boat is near goal point, maintain heading to heading of whale ;; This is all done with subtract-headings and some other trickery ;; turn boat towards a goal point, ;; adopt a goal heading when you get there. ;; gx is goal xcor ;; gy is goal ycor ;; gh is goal heading ;; max-change is the maximum degrees of change in heading allowed per turn ;; heading-diff is the difference bewteen our heading and some desired heading ;; initialize to 0 let heading-diff 0 ;; if we are near the goal point... let goal-dist sqrt (gx - xcor) (gy - ycor) ifelse goal-dist < safe-range [ ;; desired heading is the goal heading set heading-diff subtract-headings gh heading ] [ ;; otherwise, desired heading is towards the goal point set heading-diff subtract-headings (towardsxy gx gy) heading ] ;; if any change is needed... if abs heading-diff != 0 [ ;; turn in the direction of the difference ;; either the amount of the difference, or the max-change amount ;; in that direction, whichever is smaller let turn-amount (min (list max (list heading-diff (- max-turn)) max-turn)) ;; change heading by that amount rt turn-amount ;; (remember, right-turn with negative angle is a left turn!) ] ; Step 3. Simplest of all. ;; though, here, there's some extra stuff added ;; to try to slow down the boat when near the station-keeping position ;; and to try to match the whale speed, without just ;; assigning ws to speed. ;; move the boat ifelse goal-dist < safe-range [ ;; if abs (speed - ws) > 5 * accel [ ifelse speed < ws [ set speed speed + accel ] [ set speed speed - accel if speed < 0 [ set speed 0 ] ] ] ] [ if speed < max-speed [ set speed speed + accel ] ] jump speed ] ] end to-report [ #a #b ] report #a * #a + #b * #b end

whale-watch

View or download the complete model file (to download: right-click, save-link-as):

-- Download whale-watch --