Wolf Sheep Predation - GoGo Plotter
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
Reflections
Working on a system with both software and physical components poses unique design challenges. The two design efforts should inform each other and co-evolve so that the program and the robot, in our case, work harmoniously. In our case we made a division of labor in a way that one of us focused more on the software and the other on the robot while we brainstormed on the problems together. A system with such distinct components turned out to be ideal for a group project.
While we worked closely together (spending almost two days in the same room), we decided to focus on different aspects of the project, with Firat focusing mostly on the construction of the robot, and with Arthur focusing mostly on the code.
Firat
Since I mostly focused on building the robot I will focus more on the construction of the physical components of the seismograph in this reflection.
Since I mostly focused on building the robot I will focus more on the construction of the physical components of the seismograph in this reflection. First of all, I never thought that playing with technic Legos as a child would one day help me as a postdoc. Yes, Legos help you develop an understanding of how in a system different components come together and how a change in one part affects the system. I am not talking about these in direct benefits. In a very tangible way as soon as I poured all the Lego parts on the table I was a child again and my knowledge of the tiny pieces of Legos was a live (except I didn't have a brother trying to break what I made). One challenge was not having all the necessary parts (particularly the flat gear), but I was able to come up with a relatively less effective but working solution. Once I built the first prototype Arthur was already done with the software prototype. We brought the software and the robot together and realized that we needed to change things both with the robot and the software. We dedicated nearly two full days to complete the project. After the first prototypes were done we were engaged in a constant cycle of fixing problems, bringing the parts together and testing and fixing problems again. We continuously brainstormed about how to change the robot and the software and sometimes had overly ambitious ideas that had to be scaled down due to practical concerns (lack of parts & time). As you can see in the power point file we listed some of these unrealized design ideas, that might come to life in our next project. Overall this was a very enjoyable project to work on.
Arthur
I really enjoyed this project! Unlike Firat, I had no prior experience with building robots, and Firat immediately noticed problems about our initial robot sketches that I would have never been able to see. Particuarly things about structural integrity and how much (or little) resistance we could have given our small motors. Regardless, having something tangible to work with, and coding for something in the "real world" added perspectives to coding in NetLogo that I really enjoyed wrestling with.
The biggest challenge was that time matters very little in NetLogo, but plays a huge role when coding to manipulate physical objects. The Wolf Sheep predation model typically runs 30-50 ticks / second on my computer, but I had to slow down the model to a point where it runs only one tick every second or two. I first wanted our robot to do continuous plotting, in which the change in the sheep population would determine the speed of the pen (giving a more steep slope when the increase is larger). However, when we looked at the building materials available, we realized that this would require a broader piece of paper than we could accommodate for. Instead, I decided to have the pen-motor always at the same speed and simply reversing if the population started rising or falling.
Another challenge was with using the GoGo board. Sometimes it would die with no other feedback than an ominous beep. After some hours of trial and error and discussing what could cause this, we agreed that the problem was with the GoGo Board getting too many instructions in too little time. Because of this I slowed down the execution of the model even more, but when we then combined the code and the robot, the motor that moved the paper and the motor that moved the pen were out of sync. I fixed that by having the paper run continuously rather than discreetly, and only giving instructions to the pen-motor. I also really would have liked a 'portOn?' primitive. I couldn't find the GoGo board api or I would have just written that into the jar. Oh well.
All in all a super fun project. I am actually surprised at how much I enjoyed working with things that are not "just" code. Maybe this whole tangible/robotics/body stuff is worth spending more time on?
Comments and Questions
extensions [gogo] globals [ ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;; @FIrat, all new global parameters for our go go board version ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; grass? grass-regrowth-time penmovetimer ;; timer for moving pen plotting? ;; have we started plotting yet lastdsheeppos? ;; was the last change in sheep population positive? lastsheepcount grass ;; keep track of how much grass there is serial-port ;; different on different operating systems paperstarted? ;; boolean for whether paper has been started ] ;; Sheep and wolves are both breeds of turtle. breed [sheep a-sheep] ;; sheep is its own plural, so we use "a-sheep" as the singular. breed [wolves wolf] turtles-own [energy] ;; both wolves and sheep have energy patches-own [countdown] to setup clear-all ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;; @Firat, our new setup procedures ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; setup-gogo ;; set last dsheep to positive set lastdsheeppos? true ;; sets lastsheepcount to 155 because that is just about the mean sheep count with the currently setup parameters ;; and so that therefore works as the starting point for the pen set lastsheepcount 155 set grass? true set grass-regrowth-time 30 set paperstarted? false set plotting? false ;; set the penmovetimer to silly high number so it does not start at first set penmovetimer -1 ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;; @Firat, this is the old code ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;; "old" predation model code ask patches [ set pcolor green ] ;; check GRASS? switch. ;; if it is true, then grass grows and the sheep eat it ;; if it false, then the sheep don't need to eat if grass? [ ask patches [ set countdown random grass-regrowth-time ;; initialize grass grow clocks randomly set pcolor one-of [green brown] ] ] set-default-shape sheep "sheep" create-sheep initial-number-sheep ;; create the sheep, then initialize their variables [ set color white set size 1.5 ;; easier to see set label-color blue - 2 set energy random (2 * sheep-gain-from-food) setxy random-xcor random-ycor ] set-default-shape wolves "wolf" create-wolves initial-number-wolves ;; create the wolves, then initialize their variables [ set color black set size 1.5 ;; easier to see set energy random (2 * wolf-gain-from-food) setxy random-xcor random-ycor ] display-labels set grass count patches with [pcolor = green] reset-ticks end to go ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;; @Firat: These are our new procedures ;; we start plotting when there are exactly 155 sheep ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; if(plotting?) [ pauseanddraw ] if(count sheep = 155) [ set plotting? true ask sheep [set color red] if (not paperstarted?) [runpaper] ] ; if(count sheep = 155) ; [ ; runpaper ; movepen ; set plotting? true ; ask sheep [set color red] ; ; ] ;; if we have started plotting, we check if the pen move timer is up ;; the pen move timer is a set amount of time from the last time we started the motors ;; and is calculated in move-pen-for-time ;; if we are plotting and the pen move timer is up, we move the pen again ; if (plotting?) ; [ ; if timer > penmovetimer ; [ ; movepen ; ] ; ] ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;; @Firat OLD CODE ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; if not any? turtles [ stop ] ask sheep [ move if grass? [ set energy energy - 1 ;; deduct energy for sheep only if grass? switch is on eat-grass ] death reproduce-sheep ] ask wolves [ move set energy energy - 1 ;; wolves lose energy as they move catch-sheep death reproduce-wolves ] if grass? [ ask patches [ grow-grass ] ] set grass count patches with [pcolor = green] tick display-labels if (stop?) [stoppaper] if (not stop?) [go] end to move ;; turtle procedure rt random 50 lt random 50 fd 1 end to eat-grass ;; sheep procedure ;; sheep eat grass, turn the patch brown if pcolor = green [ set pcolor brown set energy energy + sheep-gain-from-food ;; sheep gain energy by eating ] end to reproduce-sheep ;; sheep procedure if random-float 100 < sheep-reproduce [ ;; throw "dice" to see if you will reproduce set energy (energy / 2) ;; divide energy between parent and offspring hatch 1 [ rt random-float 360 fd 1 ] ;; hatch an offspring and move it forward 1 step ] end to reproduce-wolves ;; wolf procedure if random-float 100 < wolf-reproduce [ ;; throw "dice" to see if you will reproduce set energy (energy / 2) ;; divide energy between parent and offspring hatch 1 [ rt random-float 360 fd 1 ] ;; hatch an offspring and move it forward 1 step ] end to catch-sheep ;; wolf procedure let prey one-of sheep-here ;; grab a random sheep if prey != nobody ;; did we get one? if so, [ ask prey [ die ] ;; kill it set energy energy + wolf-gain-from-food ] ;; get energy from eating end to death ;; turtle procedure ;; when energy dips below zero, die if energy < 0 [ die ] end to grow-grass ;; patch procedure ;; countdown on brown patches: if reach 0, grow some grass if pcolor = brown [ ifelse countdown <= 0 [ set pcolor green set countdown grass-regrowth-time ] [ set countdown countdown - 1 ] ] end to display-labels ask turtles [ set label "" ] if show-energy? [ ask wolves [ set label round energy ] if grass? [ ask sheep [ set label round energy ] ] ] end ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;; Go go specific code ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;; setup go go board to setup-gogo set serial-port user-one-of "Select a port:" gogo:ports gogo:open serial-port repeat 5 [ if not gogo:ping [ user-message "The GoGo Board is not responding." ] ] gogo:talk-to-output-ports [ "a" "b" "b" "d" ] ;; sets the speed of both pen and paper to 1 gogo:talk-to-output-ports [ "a" ] gogo:set-output-port-power 1 gogo:talk-to-output-ports [ "b" ] gogo:set-output-port-power 1 end to movepen ;; find out the change in number of sheep ;; if there are more than 200 sheep or less than 110, the graph flatlines at min or max (which is why we ;; use a fake sheep count temp var) let fakesheepcount 0 if count sheep > 200 [set fakesheepcount 200] if count sheep < 110 [set fakesheepcount 110] if fakesheepcount = 0 [set fakesheepcount count sheep] ;; find change in sheep let dsheep fakesheepcount - lastsheepcount ; if abs dsheep < 30 [stop] ;; swap out lastsheepcount for current sheep count set lastsheepcount count sheep ;; reverse if last change was positive and it is now negative or vice versa if ((lastdsheeppos? and dsheep < 0) or (not lastdsheeppos? and dsheep > 0)) [ show "reverse" ;; print debug show dsheep ;; print debug ;; "reverse" last change positive bool set lastdsheeppos? not lastdsheeppos? ;; reverse pen stoppen reversepen ] ;; move the pen for 10 ms per sheep. Abs because otherwise we will set it to negative time and it will not work. move-pen-for-time abs dsheep * .5 end ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;; @Firat new code, our go go related stuff ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; to gogo-ping carefully [ if not gogo:ping [ user-message "Unable to ping GoGo Board." ] ] [ user-message error-message ] end to move-pen-for-time [time] gogo:talk-to-output-ports [ "a" ] gogo:output-port-on ;; set the timer set penmovetimer time reset-timer end to runpen gogo:talk-to-output-ports [ "a" ] gogo:output-port-on end to stoppen gogo:talk-to-output-ports [ "a" ] gogo:output-port-off end to runpaper gogo:talk-to-output-ports [ "b" ] gogo:output-port-on end to stoppaper gogo:talk-to-output-ports [ "b" ] gogo:output-port-off end to reversepen gogo:talk-to-output-ports [ "a" ] gogo:output-port-reverse end to reversepaper gogo:talk-to-output-ports [ "b" ] gogo:output-port-reverse end to pauseanddraw ;; find out the change in number of sheep ;; if there are more than 200 sheep or less than 110, the graph flatlines at min or max ;; so we either kill extra sheep or make some if there are too few let fakesheepcount 0 if count sheep > 200 [ask n-of (count sheep - 200) sheep [die]] if count sheep < 110 [ create-sheep (110 - count sheep) ;; create the sheep, then initialize their variables [ set color white set size 1.5 ;; easier to see set label-color blue - 2 set energy random (2 * sheep-gain-from-food) setxy random-xcor random-ycor ] ] if fakesheepcount = 0 [set fakesheepcount count sheep] ;; find change in sheep let dsheep fakesheepcount - lastsheepcount set lastsheepcount fakesheepcount ;; reverse if last change was positive and it is now negative or vice versa if ((lastdsheeppos? and dsheep < 0) or (not lastdsheeppos? and dsheep > 0)) [ ;; wait a second so that go go board does not get confused wait 1 show "reverse" ;; print debug ;; "reverse" last change positive bool set lastdsheeppos? not lastdsheeppos? ;; reverse pen reversepen ] show dsheep ;; print debug ; runpaper if dsheep != 0 [ runpen wait abs (dsheep * .01) ] ; stoppaper stoppen end ; Copyright 1997 Uri Wilensky. ; See Info tab for full copyright and license.
There is only one version of this model, created over 13 years ago by Arthur Hjorth.
Attached files
No files