在宴会交响曲中有任何行人造型的例子吗?

时间:2017-07-06 07:50:00

标签: simulation repast-simphony

有什么样的行人建模在餐厅演绎吗?我是新手,并试图模拟一个简单的行人运动模拟。指向有用资源/示例的任何指针?

2 个答案:

答案 0 :(得分:1)

Andrew Crook的博客GIS和基于代理的建模(http://www.gisagents.org/)有许多有趣的行人模型链接。我认为甚至还有一些特定的Repast。

答案 1 :(得分:1)

Repast不是开放式图书馆的最佳选择,但我有幸找到了GitHub。这是我构建过一次的基本ped代理,你必须用调度程序类构建一个上下文来调用行人:

上下文:

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);
}

行人 - 这是基于“广义力模型”(来源:模拟逃脱恐慌的动态特征 - Helbing,Farkas和Vicsek - 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)
    }
}