UNPKG

rvo2

Version:

RVO2 is a node.js wrapper around the pedestrian simulator RVO2 library, an implementation of the ORCA algorithm.

140 lines (115 loc) 4.19 kB
import { Vector2, vectorvector, RVOSimulator, absSq, normalize } from '../lib/index'; // Some examples of vector functions. const v1 = new Vector2(-1, 2); const v2 = new Vector2(1, 2); const v3 = v1.mul(3); // -3, 6 console.log(`x: ${v3.x()}, y: ${v3.y()}`); const v4 = v1.sub(v2); // -2, 0 console.log(`x: ${v4.x()}, y: ${v4.y()}`); const v5 = v1.add(v2); // 0, 4 console.log(`x: ${v5.x()}, y: ${v5.y()}`); function setupScenario(sim: RVOSimulator, goals: vectorvector) { sim.setTimeStep(0.25); /* Specify the default parameters for agents that are subsequently added. */ sim.setAgentDefaults(15, 10, 5, 5, 2, 2); /* * Add agents, specifying their start position, and store their goals on the * opposite side of the environment. */ for (var i = 0; i < 5; ++i) { for (var j = 0; j < 5; ++j) { var index = sim.addAgent(new Vector2(55 + i * 10, 55 + j * 10)); goals[index] = new Vector2(-75, -75); index = sim.addAgent(new Vector2(-55 - i * 10, 55 + j * 10)); goals[index] = new Vector2(75, -75); index = sim.addAgent(new Vector2(55 + i * 10, -55 - j * 10)); goals[index] = new Vector2(-75, 75); index = sim.addAgent(new Vector2(-55 - i * 10, -55 - j * 10)); goals[index] = new Vector2(75, 75); } } /* * Add (polygonal) obstacles, specifying their vertices in counterclockwise * order. */ const obstacle1 = new vectorvector(4) , obstacle2 = new vectorvector(4) , obstacle3 = new vectorvector(4) , obstacle4 = new vectorvector(4); obstacle1[0] = new Vector2(-10, 40); obstacle1[1] = new Vector2(-40, 40); obstacle1[2] = new Vector2(-40, 10); obstacle1[3] = new Vector2(-10, 10); obstacle2[0] = new Vector2(10, 40); obstacle2[1] = new Vector2(10, 10); obstacle2[2] = new Vector2(40, 10); obstacle2[3] = new Vector2(40, 40); obstacle3[0] = new Vector2(10, -40); obstacle3[1] = new Vector2(40, -40); obstacle3[2] = new Vector2(40, -10); obstacle3[3] = new Vector2(10, -10); obstacle4[0] = new Vector2(-10, -40); obstacle4[1] = new Vector2(-10, -10); obstacle4[2] = new Vector2(-40, -10); obstacle4[3] = new Vector2(-40, -40); sim.addObstacle(obstacle1); sim.addObstacle(obstacle2); sim.addObstacle(obstacle3); sim.addObstacle(obstacle4); /* Process the obstacles so that they are accounted for in the simulation. */ sim.processObstacles(); } function updateVisualization(sim: RVOSimulator) { /* Output the current global time. */ const time = sim.getGlobalTime(); console.log(`Time: ${time}`); /* Output the current position of all the agents. */ for (let i = 0; i < sim.getNumAgents(); ++i) { const p = sim.getAgentPosition(i); console.log(`#${i}) x: ${p.x()}, y: ${p.y()}`); } } function setPreferredVelocity(sim: RVOSimulator, goals: vectorvector) { for (var i = 0; i < sim.getNumAgents(); i++) { const delta = goals[i].sub(sim.getAgentPosition(i)); /* * Perturb a little to avoid deadlocks due to perfect symmetry. */ const angle = Math.random() * 2.0 * Math.PI; const dist = Math.random() * 0.0001; var goalVector = new Vector2(delta.x() + dist * Math.cos(angle), delta.y() + dist * Math.sin(angle)); if (absSq(goalVector) > 1.0) { goalVector = normalize(goalVector); } sim.setAgentPrefVelocity(i, goalVector); } } function reachedGoal(sim: RVOSimulator, goals: vectorvector) { /* Check if all agents have reached their goals. */ for (var i = 0; i < sim.getNumAgents(); ++i) { const dist = sim.getAgentPosition(i).sub(goals[i]); if (absSq(dist) > 400) { // 400 <= 20 x 20 return false; } } return true; } function main(debug = false) { const nbrAgents = 100; const sim = new RVOSimulator(); const goals = new vectorvector(nbrAgents); setupScenario(sim, goals); // sim.addObstacle(vv); var i = 0; do { if (++i % 10 === 0) { console.log('TIME: ' + i); } setPreferredVelocity(sim, goals); if (debug) { updateVisualization(sim); } sim.doStep(); } while (!reachedGoal(sim, goals)); console.log('Done'); } main();