LCOV - code coverage report
Current view: top level - AP_Gripper - AP_Gripper_EPM.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 30 47 63.8 %
Date: 2026-09-09 11:02:08 Functions: 6 9 66.7 %

          Line data    Source code
       1             : /*
       2             :  * AP_Gripper_EPM.cpp
       3             :  *
       4             :  *  Created on: DEC 6, 2013
       5             :  *      Author: Andreas Jochum
       6             :  *              Pavel Kirienko <[email protected]> - UAVCAN support
       7             :  *              Peter Barker - moved into AP_Gripper_EPM
       8             :  */
       9             : 
      10             : #include "AP_Gripper_EPM.h"
      11             : 
      12             : #if AP_GRIPPER_EPM_ENABLED
      13             : 
      14             : #include <AP_HAL/AP_HAL.h>
      15             : #include <AP_BoardConfig/AP_BoardConfig.h>
      16             : #include <GCS_MAVLink/GCS.h>
      17             : #include <AP_Logger/AP_Logger.h>
      18             : #include <SRV_Channel/SRV_Channel.h>
      19             : 
      20             : #ifdef UAVCAN_NODE_FILE
      21             : #include <fcntl.h>
      22             : #include <stdio.h>
      23             : #endif
      24             : 
      25             : extern const AP_HAL::HAL& hal;
      26             : 
      27           2 : AP_Gripper_EPM::AP_Gripper_EPM(struct AP_Gripper::Backend_Config &_config) :
      28           2 :     AP_Gripper_Backend(_config) { }
      29             : 
      30           2 : void AP_Gripper_EPM::init_gripper()
      31             : {
      32             : #ifdef UAVCAN_NODE_FILE
      33             :     _uavcan_fd = ::open(UAVCAN_NODE_FILE, O_CLOEXEC);
      34             :     // https://ardupilot.club/dev/docs/learning-ardupilot-uarts-and-the-console.html
      35             :     ::printf("EPM: DroneCAN fd %d\n", _uavcan_fd);
      36             : #endif
      37             : 
      38             :     // initialise the EPM to the neutral position
      39           2 :     neutral();
      40           2 : }
      41             : 
      42             : // Refer to http://uavcan.org/Specification/7._List_of_standard_data_types/#uavcanequipmenthardpoint
      43             : struct UAVCANCommand {
      44             :     uint8_t hardpoint_id = 0;
      45             :     uint16_t command = 0;
      46             : };
      47             : 
      48             : // grab - move the epm pwm output to the grab position
      49           8 : void AP_Gripper_EPM::grab()
      50             : {
      51             :     // flag we are active and grabbing cargo
      52           8 :     config.state = AP_Gripper::STATE_GRABBING;
      53             : 
      54             :     // capture time
      55           8 :     _last_grab_or_release = AP_HAL::millis();
      56             : 
      57             : #ifdef UAVCAN_IOCS_HARDPOINT_SET
      58             :     if (should_use_uavcan()) {
      59             :         const UAVCANCommand cmd = make_uavcan_command(1);
      60             :         (void)ioctl(_uavcan_fd, UAVCAN_IOCS_HARDPOINT_SET, reinterpret_cast<unsigned long>(&cmd));
      61             :     }
      62             :     else
      63             : #endif
      64             :     {
      65             :         // move the servo output to the grab position
      66           8 :         SRV_Channels::set_output_pwm(SRV_Channel::k_gripper, config.grab_pwm);
      67             :     }
      68           8 :     GCS_SEND_TEXT(MAV_SEVERITY_INFO, "Gripper load grabbing");
      69           8 :     LOGGER_WRITE_EVENT(LogEvent::GRIPPER_GRAB);
      70           8 : }
      71             : 
      72             : // release - move epm pwm output to the release position
      73           8 : void AP_Gripper_EPM::release()
      74             : {
      75             :     // flag we are releasing cargo
      76           8 :     config.state = AP_Gripper::STATE_RELEASING;
      77             : 
      78             :     // capture time
      79           8 :     _last_grab_or_release = AP_HAL::millis();
      80             : 
      81             : #ifdef UAVCAN_IOCS_HARDPOINT_SET
      82             :     if (should_use_uavcan()) {
      83             :         const UAVCANCommand cmd = make_uavcan_command(0);
      84             :         (void)ioctl(_uavcan_fd, UAVCAN_IOCS_HARDPOINT_SET, reinterpret_cast<unsigned long>(&cmd));
      85             :     }
      86             :     else
      87             : #endif
      88             :     {
      89             :         // move the servo to the release position
      90           8 :         SRV_Channels::set_output_pwm(SRV_Channel::k_gripper, config.release_pwm);
      91             :     }
      92           8 :     GCS_SEND_TEXT(MAV_SEVERITY_INFO, "Gripper load releasing");
      93           8 :     LOGGER_WRITE_EVENT(LogEvent::GRIPPER_RELEASE);
      94           8 : }
      95             : 
      96             : // neutral - return the epm pwm output to the neutral position
      97           2 : void AP_Gripper_EPM::neutral()
      98             : {
      99           2 :     if (!should_use_uavcan()) {
     100             :         // move the servo to the off position
     101           2 :         SRV_Channels::set_output_pwm(SRV_Channel::k_gripper, config.neutral_pwm);
     102             :     }
     103           2 : }
     104             : 
     105             : // update - moves the pwm back to neutral after the timeout has passed
     106             : // should be called at at least 10hz
     107         860 : void AP_Gripper_EPM::update_gripper()
     108             : {
     109             :     // move EPM PWM output back to neutral after the last grab or release
     110         860 :     if (AP_HAL::millis() - _last_grab_or_release > EPM_RETURN_TO_NEUTRAL_MS) {
     111         817 :         if (config.state == AP_Gripper::STATE_GRABBING) {
     112           0 :             neutral();
     113           0 :             config.state = AP_Gripper::STATE_GRABBED;
     114         817 :         } else if (config.state == AP_Gripper::STATE_RELEASING) {
     115           0 :             neutral();
     116           0 :             config.state = AP_Gripper::STATE_RELEASED;
     117             :         }
     118             :     }
     119             : 
     120             :     // re-grab the cargo intermittently
     121        1720 :     if (config.state == AP_Gripper::STATE_GRABBED &&
     122         860 :         (config.regrab_interval > 0) &&
     123           0 :         (AP_HAL::millis() - _last_grab_or_release > ((uint32_t)config.regrab_interval * 1000))) {
     124           0 :         grab();
     125             :     }
     126         860 : }
     127             : 
     128           0 : UAVCANCommand AP_Gripper_EPM::make_uavcan_command(uint16_t command) const
     129             : {
     130           0 :     UAVCANCommand cmd;
     131           0 :     cmd.hardpoint_id = config.uavcan_hardpoint_id;
     132           0 :     cmd.command = command;
     133           0 :     return cmd;
     134             : }
     135             : 
     136             : 
     137           0 : bool AP_Gripper_EPM::released() const
     138             : {
     139             :     // we assume instanteous releasing ATM:
     140           0 :     return (config.state == AP_Gripper::STATE_GRABBED ||
     141           0 :             config.state == AP_Gripper::STATE_GRABBING);
     142             : }
     143             : 
     144           0 : bool AP_Gripper_EPM::grabbed() const
     145             : {
     146             :     // we assume instanteous grabbing ATM:
     147           0 :     return (config.state == AP_Gripper::STATE_GRABBED ||
     148           0 :             config.state == AP_Gripper::STATE_GRABBING);
     149             : }
     150             : 
     151             : #endif  // AP_GRIPPER_EPM_ENABLED

Generated by: LCOV version 1.14