linda
linda

Reputation: 117

How to make agent flock in their group using BOIDS rule in Netlogo?

Here is what I want to do:

  1. I need all agents move forward in a group by using BOIDS rule

  2. I want them to be able to turn around after they meet the wall (my world is not wrap, they can't penetrate the wall to reach the other side of the world)

here is my code:

globals [nearest-teammates teammmembers]

turtles-own [ myteamset teamID myID teammatesID ]

to setup-groups

  let teamCounter 1 
  ask turtles [
    if myteamset = nobody [
      let possible-teammates other turtles with [ myteamset = nobody ]
      ifelse count possible-teammates > 1 [
        set myteamset ( turtle-set self n-of 2 possible-teammates )
        let ids sort [myID] of myteamset
        set teammmembers myteamset
        set nearest-teammates min-one-of myteamset[distance myself]

        let tempteam teamCounter         
        set teamCounter teamCounter + 1
        ask myteamset [
          set teammatesID ids
          set myteamset teammmembers
          set teamID tempteam
        ]

      ] [
        show "Not enough turtles to make a new team!"
      ]
    ]
  ]
end

flocking part:

to move-in-groups

  let teamNumbers remove-duplicates [teamID] of turtles
  foreach teamNumbers [                         
    ask one-of turtles with [ teamID = ? ] [
      if myteamset != nobody [
        ask myteamset [
        set  heading mean-heading [ heading ] of myteamset
         ifelse distance one-of turtles with [ teamID = ? ] < 3
         [separate]
         [align
           cohere]]
          fd 1 ]]]
end

helpers code

to-report mean-heading [ headings ]
  let mean-x mean map sin headings
  let mean-y mean map cos headings
  report atan mean-x mean-y
end

to align  
  turn-towards average-flockmate-heading max-align-turn
end

to cohere  
  turn-towards average-heading-towards-flockmates max-cohere-turn
end


to separate  
  turn-away ([heading] of nearest-teammates) max-separate-turn
end

to turn-away [new-heading max-turn]  
  turn-at-most (subtract-headings heading new-heading) max-turn
end

to-report average-heading-towards-flockmates  
  let x-component mean [sin (towards myself + 180)] of nearest-teammates
  let y-component mean [cos (towards myself + 180)] of nearest-teammates
  ifelse x-component = 0 and y-component = 0
    [ report heading ]
    [ report atan x-component y-component ]
end

to-report average-flockmate-heading  
  let x-component sum [dx] of nearest-teammates
  let y-component sum [dy] of nearest-teammates
  ifelse x-component = 0 and y-component = 0
    [ report heading ]
    [ report atan x-component y-component ]
end

to turn-at-most [turn max-turn]  
  ifelse abs turn > max-turn
    [ ifelse turn > 0
        [ rt max-turn ]
        [ lt max-turn ] ]
    [ rt turn ]
end

to turn-towards [new-heading max-turn]  
  turn-at-most (subtract-headings new-heading heading) max-turn
end

The error I get:

SUM expected input to be a list but got the number -0.961261695938319 instead.
error while turtle 4 running SUM
  called by procedure AVERAGE-FLOCKMATE-HEADING
  called by procedure ALIGN
  called by (command task from: procedure MOVE-IN-GROUPS)
  called by procedure MOVE-IN-GROUPS
  called by procedure GO
  called by Button 'go'

What should I do? I need help... .·´¯(>▂<)´¯·. Thank you for your time.

Upvotes: 0

Views: 115

Answers (1)

Nicolas Payette
Nicolas Payette

Reputation: 14972

The error you are getting happens on this line:

let x-component sum [dx] of nearest-teammates

NetLogo is telling you that you tried to pass a single number to sum instead of passing it a list. How could that happen? It would happen if nearest-teammates contained a single agent instead of an agentset.

So let's look at where you define nearest-teammates:

set nearest-teammates min-one-of myteamset[distance myself]

Can you see the problem? You're using min-one-of, which does give you a single agent!

How could you get, for example, the 10 closest agents instead of just the closest one? Fortunately, NetLogo has a primitive that does just that: min-n-of. Here is how you would use it:

set nearest-teammates min-n-of 10 myteamset [ distance myself ]

Replace 10 with the number of teammates you want, of course.

Upvotes: 1

Related Questions