LCOV - code coverage report
Current view: top level - AP_Proximity - AP_Proximity_TeraRangerTower.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 39 43 90.7 %
Date: 2026-09-09 11:02:08 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :    This program is free software: you can redistribute it and/or modify
       3             :    it under the terms of the GNU General Public License as published by
       4             :    the Free Software Foundation, either version 3 of the License, or
       5             :    (at your option) any later version.
       6             : 
       7             :    This program is distributed in the hope that it will be useful,
       8             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
       9             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      10             :    GNU General Public License for more details.
      11             : 
      12             :    You should have received a copy of the GNU General Public License
      13             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      14             :  */
      15             : 
      16             : #include "AP_Proximity_config.h"
      17             : 
      18             : #if AP_PROXIMITY_TERARANGERTOWER_ENABLED
      19             : 
      20             : #include "AP_Proximity_TeraRangerTower.h"
      21             : 
      22             : #include <AP_HAL/AP_HAL.h>
      23             : #include <AP_Math/crc.h>
      24             : #include <ctype.h>
      25             : #include <stdio.h>
      26             : 
      27             : extern const AP_HAL::HAL& hal;
      28             : 
      29             : // update the state of the sensor
      30        8366 : void AP_Proximity_TeraRangerTower::update(void)
      31             : {
      32        8366 :     if (_uart == nullptr) {
      33           0 :         return;
      34             :     }
      35             : 
      36             :     // process incoming messages
      37        8366 :     read_sensor_data();
      38             : 
      39             :     // check for timeout and set health status
      40        8366 :     if ((_last_distance_received_ms == 0) || (AP_HAL::millis() - _last_distance_received_ms > PROXIMITY_TRTOWER_TIMEOUT_MS)) {
      41           0 :         set_status(AP_Proximity::Status::NoData);
      42             :     } else {
      43        8366 :         set_status(AP_Proximity::Status::Good);
      44             :     }
      45             : }
      46             : 
      47             : // get maximum and minimum distances (in meters) of primary sensor
      48        2510 : float AP_Proximity_TeraRangerTower::distance_max_m() const
      49             : {
      50        2510 :     return 4.5f;
      51             : }
      52         210 : float AP_Proximity_TeraRangerTower::distance_min_m() const
      53             : {
      54         210 :     return 0.20f;
      55             : }
      56             : 
      57             : // check for replies from sensor, returns true if at least one message was processed
      58        8366 : bool AP_Proximity_TeraRangerTower::read_sensor_data()
      59             : {
      60        8366 :     if (_uart == nullptr) {
      61           0 :         return false;
      62             :     }
      63             : 
      64        8366 :     uint16_t message_count = 0;
      65        8366 :     int16_t nbytes = _uart->available();
      66             : 
      67       12394 :     while (nbytes-- > 0) {
      68             :         uint8_t c;
      69        4028 :         if (!_uart->read(c)) {
      70           0 :             return false;
      71             :         }
      72        4028 :         if (char(c) == 'T' ) {
      73         212 :             buffer_count = 0;
      74             :         }
      75             : 
      76        4028 :         buffer[buffer_count++] = c;
      77             : 
      78             :         // we should always read 19 bytes THxxxxxxxxxxxxxxxxC
      79        4028 :         if (buffer_count >= 19){
      80         212 :             buffer_count = 0;
      81             : 
      82             :             // check if message has right CRC
      83         212 :             if (crc_crc8(buffer, 18) == buffer[18]){
      84         212 :                 update_sector_data(0,   UINT16_VALUE(buffer[2],  buffer[3]));   // d1
      85         212 :                 update_sector_data(45,  UINT16_VALUE(buffer[16], buffer[17]));  // d8
      86         212 :                 update_sector_data(90,  UINT16_VALUE(buffer[14], buffer[15]));  // d7
      87         212 :                 update_sector_data(135, UINT16_VALUE(buffer[12], buffer[13]));  // d6
      88         212 :                 update_sector_data(180, UINT16_VALUE(buffer[10], buffer[11]));  // d5
      89         212 :                 update_sector_data(225, UINT16_VALUE(buffer[8],  buffer[9]));   // d4
      90         212 :                 update_sector_data(270, UINT16_VALUE(buffer[6],  buffer[7]));   // d3
      91         212 :                 update_sector_data(315, UINT16_VALUE(buffer[4],  buffer[5]));   // d2
      92             : 
      93         212 :                 message_count++;
      94             :             }
      95             :         }
      96             :     }
      97        8366 :     return (message_count > 0);
      98             : }
      99             : 
     100             : // process reply
     101        1696 : void AP_Proximity_TeraRangerTower::update_sector_data(int16_t angle_deg, uint16_t distance_mm)
     102             : {
     103             :     // Get location on 3-D boundary based on angle to the object
     104        1696 :     const AP_Proximity_Boundary_3D::Face face = frontend.boundary.get_face(angle_deg);
     105        1696 :     if ((distance_mm != 0xffff) && !ignore_reading(angle_deg, distance_mm * 0.001f, false)) {
     106         849 :         frontend.boundary.set_face_attributes(face, angle_deg, ((float) distance_mm) / 1000, state.instance);
     107             :         // update OA database
     108         849 :         database_push(angle_deg, ((float) distance_mm) / 1000);
     109             :     } else {
     110         847 :         frontend.boundary.reset_face(face, state.instance);
     111             :     }
     112        1696 :     _last_distance_received_ms = AP_HAL::millis();
     113        1696 : }
     114             : 
     115             : #endif // AP_PROXIMITY_TERARANGERTOWER_ENABLED

Generated by: LCOV version 1.14