Working object perception
This commit is contained in:
parent
55cca93d67
commit
470b2e21e5
128
Perception.cpp
128
Perception.cpp
@ -3,11 +3,16 @@
|
|||||||
#include "DistanceSensor.h"
|
#include "DistanceSensor.h"
|
||||||
#include "Switch.h"
|
#include "Switch.h"
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
Perception::Perception() {}
|
Perception::Perception() {
|
||||||
|
for (unsigned char objIx = 0; objIx < maxObjectCount; objIx++)
|
||||||
|
this->perceivedObjects[objIx] = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
Perception::Perception(Placement *sensors, unsigned int sensorCount) {
|
Perception::Perception(Placement *sensors, unsigned int sensorCount)
|
||||||
|
: Perception() {
|
||||||
this->sensorCount = sensorCount;
|
this->sensorCount = sensorCount;
|
||||||
this->sensorPlacements = (Placement *)sensors;
|
this->sensorPlacements = (Placement *)sensors;
|
||||||
}
|
}
|
||||||
@ -100,3 +105,122 @@ bool Perception::ObjectNearby(float direction, float range) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Oject perception
|
||||||
|
***/
|
||||||
|
|
||||||
|
PerceivedObject::PerceivedObject() {
|
||||||
|
this->id = 0;
|
||||||
|
this->confidence = maxConfidence;
|
||||||
|
this->position = Polar(0, INFINITY);
|
||||||
|
this->radius = INFINITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
PerceivedObject::PerceivedObject(Polar position, float radius)
|
||||||
|
: PerceivedObject() {
|
||||||
|
this->position = position;
|
||||||
|
this->radius = radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PerceivedObject::IsTheSameAs(PerceivedObject *otherObj) {
|
||||||
|
if (id != 0 && id == otherObj->id)
|
||||||
|
return true;
|
||||||
|
if (abs(position.distance - otherObj->position.distance) > equalityDistance)
|
||||||
|
return false;
|
||||||
|
if (abs(position.angle - otherObj->position.angle) > equalityAngle)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PerceivedObject::DegradeConfidence(float deltaTime) {
|
||||||
|
unsigned char confidenceDrop =
|
||||||
|
(unsigned char)((float)confidenceDropSpeed * deltaTime);
|
||||||
|
// Make sure the confidence always drops
|
||||||
|
if (confidenceDrop == 0)
|
||||||
|
confidenceDrop = 1;
|
||||||
|
|
||||||
|
if (confidence <= confidenceDrop) {
|
||||||
|
// object is dead
|
||||||
|
confidence = 0;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
confidence -= confidenceDrop;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerceivedObject::Refresh(Polar position, float radius) {
|
||||||
|
this->position = position;
|
||||||
|
this->radius = radius;
|
||||||
|
this->confidence = maxConfidence;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Perception::AddPerceivedObject(PerceivedObject *obj) {
|
||||||
|
unsigned char farthestObjIx = 0;
|
||||||
|
unsigned char availableSlotIx = 0;
|
||||||
|
for (unsigned char objIx = 0; objIx < maxObjectCount; objIx++) {
|
||||||
|
// Is this slot available?
|
||||||
|
if (perceivedObjects[objIx] == nullptr) {
|
||||||
|
availableSlotIx = objIx;
|
||||||
|
}
|
||||||
|
// Do we see the same object?
|
||||||
|
else if (obj->IsTheSameAs(perceivedObjects[objIx])) {
|
||||||
|
perceivedObjects[objIx]->Refresh(obj->position, obj->radius);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Is this the fartest object we see?
|
||||||
|
else if (perceivedObjects[farthestObjIx] == nullptr ||
|
||||||
|
(perceivedObjects[objIx]->position.distance >
|
||||||
|
perceivedObjects[farthestObjIx]->position.distance)) {
|
||||||
|
farthestObjIx = objIx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if an perception slot is available (we currently see less than the
|
||||||
|
// max number of objects)
|
||||||
|
if (availableSlotIx < maxObjectCount) {
|
||||||
|
// a slot is available
|
||||||
|
perceivedObjects[availableSlotIx] = obj;
|
||||||
|
}
|
||||||
|
// If this object is closer than the farthest object, then replace it
|
||||||
|
else if (obj->position.distance <
|
||||||
|
perceivedObjects[farthestObjIx]->position.distance) {
|
||||||
|
perceivedObjects[farthestObjIx] = obj;
|
||||||
|
// we may want to destroy the fartest object, but if it is created
|
||||||
|
// externally, other links may still exist...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char Perception::PerceivedObjectCount() {
|
||||||
|
unsigned char objectCount = 0;
|
||||||
|
for (unsigned char objIx = 0; objIx < maxObjectCount; objIx++) {
|
||||||
|
if (perceivedObjects[objIx] != nullptr)
|
||||||
|
objectCount++;
|
||||||
|
}
|
||||||
|
return objectCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Perception::Update(float currentTimeMs) {
|
||||||
|
float deltaTime = currentTimeMs - lastUpdateTimeMs;
|
||||||
|
if (deltaTime <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lastUpdateTimeMs = currentTimeMs;
|
||||||
|
|
||||||
|
for (unsigned char objIx = 0; objIx < maxObjectCount; objIx++) {
|
||||||
|
PerceivedObject *obj = perceivedObjects[objIx];
|
||||||
|
if (obj == nullptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (obj->DegradeConfidence(deltaTime) == false) {
|
||||||
|
// delete obj
|
||||||
|
perceivedObjects[objIx] = nullptr;
|
||||||
|
} else {
|
||||||
|
Serial.printf("[%d] confidence: %d\n", objIx,
|
||||||
|
perceivedObjects[objIx]->confidence);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (perceivedObjects[0] != nullptr) {
|
||||||
|
}
|
||||||
|
}
|
38
Perception.h
38
Perception.h
@ -1,11 +1,33 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Placement.h"
|
#include "Placement.h"
|
||||||
|
#include "Polar.h"
|
||||||
#include "Sensor.h"
|
#include "Sensor.h"
|
||||||
|
|
||||||
namespace Passer {
|
namespace Passer {
|
||||||
namespace RoboidControl {
|
namespace RoboidControl {
|
||||||
|
|
||||||
|
class PerceivedObject {
|
||||||
|
public:
|
||||||
|
PerceivedObject();
|
||||||
|
PerceivedObject(Polar position, float radius);
|
||||||
|
|
||||||
|
static constexpr float equalityDistance = 0.3F;
|
||||||
|
static constexpr float equalityAngle = 5.0F;
|
||||||
|
bool IsTheSameAs(PerceivedObject *otherObj);
|
||||||
|
|
||||||
|
int id;
|
||||||
|
|
||||||
|
Polar position;
|
||||||
|
float radius;
|
||||||
|
|
||||||
|
static constexpr char maxConfidence = 255;
|
||||||
|
static constexpr char confidenceDropSpeed = 2;
|
||||||
|
char confidence;
|
||||||
|
bool DegradeConfidence(float deltaTime);
|
||||||
|
void Refresh(Polar position, float radius);
|
||||||
|
};
|
||||||
|
|
||||||
/// @brief Module to which keeps track of objects around the roboid
|
/// @brief Module to which keeps track of objects around the roboid
|
||||||
class Perception {
|
class Perception {
|
||||||
public:
|
public:
|
||||||
@ -70,11 +92,27 @@ public:
|
|||||||
bool ObjectNearby(float horizontalDirection, float verticalDirection,
|
bool ObjectNearby(float horizontalDirection, float verticalDirection,
|
||||||
float range = 10.0F);
|
float range = 10.0F);
|
||||||
|
|
||||||
|
// Object Perception
|
||||||
|
|
||||||
|
void AddPerceivedObject(PerceivedObject *obj);
|
||||||
|
unsigned char PerceivedObjectCount();
|
||||||
|
|
||||||
|
// mainly used for confidence update
|
||||||
|
void Update(float currentTimeMs);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// @brief The Placement of the Sensors used for Perception
|
/// @brief The Placement of the Sensors used for Perception
|
||||||
Placement *sensorPlacements = nullptr;
|
Placement *sensorPlacements = nullptr;
|
||||||
/// @brief The number of Sensors used for Perception
|
/// @brief The number of Sensors used for Perception
|
||||||
unsigned int sensorCount = 0;
|
unsigned int sensorCount = 0;
|
||||||
|
|
||||||
|
float lastUpdateTimeMs = 0;
|
||||||
|
|
||||||
|
static const unsigned char maxObjectCount = 7;
|
||||||
|
PerceivedObject
|
||||||
|
*perceivedObjects[maxObjectCount]; // 7 is typically the maximum number of
|
||||||
|
// object which can be tracked by a
|
||||||
|
// human
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace RoboidControl
|
} // namespace RoboidControl
|
||||||
|
@ -6,3 +6,8 @@ Roboid::Roboid(Perception* perception, Propulsion* propulsion) {
|
|||||||
this->perception = perception;
|
this->perception = perception;
|
||||||
this->propulsion = propulsion;
|
this->propulsion = propulsion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Roboid::Update(float currentTimeMs) {
|
||||||
|
if (perception != nullptr)
|
||||||
|
perception->Update(currentTimeMs);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user