123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- #include "AC_PolyFence_loader.h"
- extern const AP_HAL::HAL& hal;
- static const StorageAccess fence_storage(StorageManager::StorageFence);
- /*
- maximum number of fencepoints
- */
- uint8_t AC_PolyFence_loader::max_points() const
- {
- return MIN(255U, fence_storage.size() / sizeof(Vector2l));
- }
- // create buffer to hold copy of eeprom points in RAM
- // returns nullptr if not enough memory can be allocated
- void* AC_PolyFence_loader::create_point_array(uint8_t element_size)
- {
- uint32_t array_size = max_points() * element_size;
- if (hal.util->available_memory() < 100U + array_size) {
- // too risky to enable as we could run out of stack
- return nullptr;
- }
- return calloc(1, array_size);
- }
- // load boundary point from eeprom, returns true on successful load
- bool AC_PolyFence_loader::load_point_from_eeprom(uint16_t i, Vector2l& point)
- {
- // sanity check index
- if (i >= max_points()) {
- return false;
- }
- // read fence point
- point.x = fence_storage.read_uint32(i * sizeof(Vector2l));
- point.y = fence_storage.read_uint32(i * sizeof(Vector2l) + sizeof(uint32_t));
- return true;
- }
- // save a fence point to eeprom, returns true on successful save
- bool AC_PolyFence_loader::save_point_to_eeprom(uint16_t i, const Vector2l& point)
- {
- // sanity check index
- if (i >= max_points()) {
- return false;
- }
- // write point to eeprom
- fence_storage.write_uint32(i * sizeof(Vector2l), point.x);
- fence_storage.write_uint32(i * sizeof(Vector2l)+sizeof(uint32_t), point.y);
- return true;
- }
- // validate array of boundary points (expressed as either floats or long ints)
- // returns true if boundary is valid
- template <typename T>
- bool AC_PolyFence_loader::boundary_valid(uint16_t num_points, const Vector2<T>* points) const
- {
- // exit immediate if no points
- if (points == nullptr) {
- return false;
- }
- // start from 2nd point as boundary contains return point (as first point)
- uint8_t start_num = 1;
- // a boundary requires at least 4 point (a triangle and last point equals first)
- if (num_points < start_num + 4) {
- return false;
- }
- // point 1 and last point must be the same. Note: 0th point is reserved as the return point
- if (!Polygon_complete(&points[start_num], num_points-start_num)) {
- return false;
- }
- // check return point is within the fence
- if (Polygon_outside(points[0], &points[1], num_points-start_num)) {
- return false;
- }
- return true;
- }
- // check if a location (expressed as either floats or long ints) is within the boundary
- // returns true if location is outside the boundary
- template <typename T>
- bool AC_PolyFence_loader::boundary_breached(const Vector2<T>& location, uint16_t num_points, const Vector2<T>* points) const
- {
- // exit immediate if no points
- if (points == nullptr) {
- return false;
- }
- // start from 2nd point as boundary contains return point (as first point)
- uint8_t start_num = 1;
- // check location is within the fence
- return Polygon_outside(location, &points[start_num], num_points-start_num);
- }
- // declare type specific methods
- template bool AC_PolyFence_loader::boundary_valid<int32_t>(uint16_t num_points, const Vector2l* points) const;
- template bool AC_PolyFence_loader::boundary_valid<float>(uint16_t num_points, const Vector2f* points) const;
- template bool AC_PolyFence_loader::boundary_breached<int32_t>(const Vector2l& location, uint16_t num_points,
- const Vector2l* points) const;
- template bool AC_PolyFence_loader::boundary_breached<float>(const Vector2f& location, uint16_t num_points,
- const Vector2f* points) const;
|