2017-07-06 4 views

答えて

1

Andrew CrookのブログGISとエージェントベースのモデリング(http://www.gisagents.org/)には、歩行者モデルへの興味深いリンクがたくさんあります。私はRepastに特有のものさえあると思う。

1

Repastはオープンライブラリには最適ではありませんが、私はGitHubを検索する運がありました。

コンテキスト:

public class RoadBuilder extends DefaultContext<Object> implements ContextBuilder<Object> { 
    context.setId("driving1"); 
    ContinuousSpaceFactory spaceFactory = 
      ContinuousSpaceFactoryFinder.createContinuousSpaceFactory(null); 
    ContinuousSpace<Object> space = 
      spaceFactory.createContinuousSpace("space",context, new SimpleCartesianAdder<Object>(), 
               new StrictBorders(), roadL, worldW); 
    clock = RunEnvironment.getInstance().getCurrentSchedule(); 
    flowSource = new Scheduler(); 
    context.add(flowSource); 
    return context; 
} 

スケジューラ:

public class Scheduler {  
    static ArrayList<Ped> allPeds; 

    @ScheduledMethod(start = 1, interval = 1, priority = 1) 
    public void doStuff() { 
     Ped addedPed = addPed(1); 
     allPeds.add(addedPed); 
     for (Ped a : allPeds) { 
      a.calc();} 
     for (Ped b : allPeds) { 
      b.walk();} 

    public Ped addPed(int direction) { 
     Context<Object> context = ContextUtils.getContext(this); 
     ContinuousSpace<Object> space = (ContinuousSpace<Object>) context.getProjection("space"); 
     Ped newPed = new Ped(space,direction); 
     context.add(newPed); 
     space.moveTo(newPed,xPlacement,yPlacement); 
     newPed.myLoc = space.getLocation(newPed); 
     return(newPed); 
} 

ここで私はあなたが歩行者を呼び出すために、スケジューラクラスとコンテキストを構築する必要があります、一度構築された基本的なPEDエージェントです歩行者 - これは「一般化された力モデル」に基づいている(出典:脱出パニックの力学的シミュレーション - ヘルビング、ファルカ、ビセク - https://arxiv.org/pdf/cond-mat/0009448.pdf

およびここに歩行者クラスがあります

public class Ped { 
    private ContinuousSpace<Object> space; 
    private List<Double> forcesX, forcesY; 
    private NdPoint endPt; 
    private Random rnd = new Random(); 
    private int age; 
    private double endPtDist, endPtTheta, critGap; 
    private double side = RoadBuilder.sidewalk; 
    private double wS, etaS, wV, etaV, sigR; //errors 
    private double m, horiz, A, B, k, r;  //interactive force constants (accT is also) 
    public NdPoint myLoc, destination; 
    public double[] v, dv, newV; 
    public double xTime, accT, maxV, xLoc, yLoc; 
    public int dir;   // dir = 1 walks up, -1 walks down 

    public void calc() { 
     myLoc = space.getLocation(this); 
     dv = accel(myLoc,dir,destination); 
     newV = sumV(v,dv); 
     newV = limitV(newV); 
    } 

    public void walk() { 
     v = newV; 
     move(myLoc,v); 
    } 

    public double[] accel(NdPoint location, int direct, NdPoint endPt) { 
     forcesX = new ArrayList<Double>(); 
     forcesY = new ArrayList<Double>(); 
     double xF, yF; 
     double[] acc; 
     xF = yF = 0; 

     //calculate heading to endpoint 
     endPtDist = space.getDistance(location, endPt); 
     double endPtDelX = endPt.getX()-location.getX(); 
     endPtTheta = FastMath.asin((double)direct*endPtDelX/endPtDist); 
     if (direct == -1) { 
      endPtTheta += Math.PI;} 

     //calculate motive force 
     Double motFx = (maxV*Math.sin(endPtTheta) - v[0])/accT; 
     Double motFy = (maxV*Math.cos(endPtTheta) - v[1])/accT; 
     forcesX.add(motFx); 
     forcesY.add(motFy); 

     //calculate interactive forces 
     //TODO: write code to make a threshold for interaction instead of the arbitrary horizon 
     for (Ped a : Scheduler.allPeds) { 
      if (a != this) { 
       NdPoint otherLoc = space.getLocation(a); 
       double otherY = otherLoc.getY(); 
       double visible = Math.signum((double)dir*(otherY-yLoc)); 
       if (visible == 1) {  //peds only affected by those in front of them 
        double absDist = space.getDistance(location, otherLoc); 
        if (absDist < horiz) { 
         double delX = location.getX()-otherLoc.getX(); 
         double delY = location.getY()-otherLoc.getY(); 
         double delXabs = Math.abs(delX); 
         double signFx = Math.signum(delX); 
         double signFy = Math.signum(delY); 
         double theta = FastMath.asin(delXabs/absDist); 
         double rij  = r + a.r; 
         Double interFx = signFx*A*Math.exp((rij-absDist)/B)*Math.sin(theta)/m; 
         Double interFy = signFy*A*Math.exp((rij-absDist)/B)*Math.cos(theta)/m; 
         forcesX.add(interFx); 
         forcesY.add(interFy);}}}} 

     //sum all forces 
     for (Double b : forcesX) { 
      xF += b;} 
     for (Double c : forcesY) { 
      yF += c;} 
     acc = new double[] {xF, yF}; 
     return acc; 
    } 

    public void move(NdPoint loc, double[] displacement) { 
     double[] zero = new double[] {0,0}; 
     double yl = loc.getY(); 
     if (displacement != zero) { 
      space.moveByDisplacement(this,displacement); 
      myLoc = space.getLocation(this);} 
    } 

    public double[] limitV(double[] input) { 
     double totalV, norm; 
     if (this.dir == 1) { 
      if (input[1] < 0) { 
       input[1] = 0;}} 
     else { 
      if (input[1] > 0) { 
       input[1] = 0;}} 
     totalV = Math.sqrt(input[0]*input[0] + input[1]*input[1]); 
     if (totalV > maxV) { 
      norm = maxV/totalV; 
      input[0] = input[0]*norm; 
      input[1] = input[1]*norm;} 
     return input; 
    } 

    public double[] sumV(double[] a, double[] b) { 
     double[] c = new double[2]; 
      for (int i = 0; i < 2; i++) { 
      c[i] = a[i] + b[i];} 
     return c; 
    }  

    public Ped(ContinuousSpace<Object> contextSpace, int direction) { 
     space = contextSpace; 
     maxV  = rnd.nextGaussian() * UserPanel.pedVsd + UserPanel.pedVavg; 
     dir  = direction; // 1 moves up, -1 moves down 
     v  = new double[] {0,(double)dir*.5*maxV}; 
     age  = 0; 

     //3-circle variables - from Helbing, et al (2000) [r from Rouphail et al 1998] 
     accT = 0.5/UserPanel.tStep;      //acceleration time 
     m  = 80;           //avg ped mass in kg 
     horiz = 5/RoadBuilder.spaceScale;     //distance at which peds affect each other 
     A  = 2000*UserPanel.tStep*UserPanel.tStep/RoadBuilder.spaceScale; //ped interaction constant (kg*space units/time units^2) 
     B  = 0.08/RoadBuilder.spaceScale;     //ped distance interaction constant (space units) 
     k  = 120000*UserPanel.tStep*UserPanel.tStep;   //wall force constant 
     r  = 0.275/RoadBuilder.spaceScale;     //ped radius (space units) 
    } 
} 
関連する問題