innovationOUtside / nbev3devsim

Ev3DevSim ipywidget in Jupyter notebooks
Apache License 2.0
5 stars 0 forks source link

Impeding progress when robot encounters a wall or obstacle #28

Open psychemedia opened 4 years ago

psychemedia commented 4 years ago

At the current time, there is no physics that impedes the progress of the robot if it encounters a wall or an obstacle, although the ultrasonic sensor will detect it.

Could we use the ultrasonic value as the basis for some physics that will stop the robot if the distance is less than a specified value? Also worth noting that the ultrasonic does not report an angle, just a distance. But maybe we could use the angle in helping us create something we could use in implementing physical blocking?

When the robot encounters an obstacle, how should we treat it? Just stop the robot moving? Should there be a physical indicator on the robot showing that it is being blocked?

The simplest route to start with might be a pointwise touch sensor that registers a wall or obstacle, although this means that the corners of the robot might "pass through" the obstacle. A complete solution would prevent motion if the envelope of the robot intersects the envelope of an obstacle.

For the walls, it should be easy enough: create a bounding box around the rectangular robot (accounts for rotation), then look to see if any of the corners are outside the canvas area. Let robot rotate as far as it can using a min() function somehow to identify the final attempted turning angle. For obstacles, which are rectangular and not rotated, it might be more pragmatic to treat the robot and the obstacles as circles and just flag a collision if they intersect (perhaps the robot and the obstacles have deformable corners!). A quick way of handling this is described in this Collision Detection and Physics tutorial:

this.circleIntersect = function(x1, y1, r1, x2, y2, r2) {

    // Calculate the distance between the two circles
    let squareDistance = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2);

    // When the distance is smaller or equal to the sum
    // of the two radius, the circles touch or overlap
    return squareDistance <= ((r1 + r2) * (r1 + r2))
}

One other thing to think about: where should this be called? In drawAll(), which itself is called from animate(). If the robot was impeded, then we'd probably want an enabled touch sensor to return true?