diff --git a/ArduBoat/BoatGeneric.h b/ArduBoat/BoatGeneric.h index 8289445440..7b7bff0eb2 100644 --- a/ArduBoat/BoatGeneric.h +++ b/ArduBoat/BoatGeneric.h @@ -47,6 +47,9 @@ static const float batteryVoltageDivRatio = 6; static const float batteryMinVolt = 10.0; static const float batteryMaxVolt = 12.4; + +static const bool useForwardReverseSwitch = true; + static const bool rangeFinderFrontEnabled = false; static const bool rangeFinderBackEnabled = false; static const bool rangeFinderLeftEnabled = false; diff --git a/ArduBoat/ControllerBoat.h b/ArduBoat/ControllerBoat.h index 7867c7ef5b..633609743e 100644 --- a/ArduBoat/ControllerBoat.h +++ b/ArduBoat/ControllerBoat.h @@ -16,9 +16,13 @@ class ControllerBoat: public AP_Controller { public: ControllerBoat(AP_Navigator * nav, AP_Guide * guide, AP_HardwareAbstractionLayer * hal) : - AP_Controller(nav, guide, hal,new AP_ArmingMechanism(hal,this,ch_sail,ch_str,0.1,-0.9,0.9), ch_mode, k_cntrl), + AP_Controller(nav, guide, hal,new AP_ArmingMechanism(hal,this,ch_thrust,ch_str,0.1,-0.9,0.9), ch_mode, k_cntrl), pidStr(new AP_Var_group(k_pidStr, PSTR("STR_")), 1, steeringP, - steeringI, steeringD, steeringIMax, steeringYMax) + steeringI, steeringD, steeringIMax, steeringYMax), + pidThrust(new AP_Var_group(k_pidThrust, PSTR("THR_")), 1, throttleP, + throttleI, throttleD, throttleIMax, throttleYMax, + throttleDFCut), _strCmd(0), _thrustCmd(0), + _rangeFinderFront() { _hal->debug->println_P(PSTR("initializing boat controller")); @@ -29,30 +33,61 @@ public: new AP_RcChannel(k_chStr, PSTR("STR_"), hal->radio, 3, 1100, 1500, 1900, RC_MODE_INOUT, false)); _hal->rc.push_back( - new AP_RcChannel(k_chSail, PSTR("SAIL_"), hal->radio, 2, 1100, 1500, + new AP_RcChannel(k_chThrust, PSTR("THR_"), hal->radio, 2, 1100, 1500, 1900, RC_MODE_INOUT, false)); + _hal->rc.push_back( + new AP_RcChannel(k_chFwdRev, PSTR("FWDREV_"), hal->radio, 4, 1100, 1500, + 1900, RC_MODE_IN, false)); + + for (uint8_t i = 0; i < _hal->rangeFinders.getSize(); i++) { + RangeFinder * rF = _hal->rangeFinders[i]; + if (rF == NULL) + continue; + if (rF->orientation_x == 1 && rF->orientation_y == 0 + && rF->orientation_z == 0) + _rangeFinderFront = rF; + } } private: // methods void manualLoop(const float dt) { _strCmd = _hal->rc[ch_str]->getRadioPosition(); - _sailCmd = _hal->rc[ch_sail]->getRadioPosition(); + _thrustCmd = _hal->rc[ch_thrust]->getRadioPosition(); + if (useForwardReverseSwitch && _hal->rc[ch_FwdRev]->getRadioPosition() < 0.0) + _thrustCmd = -_thrustCmd; } void autoLoop(const float dt) { - - // insert tacking logic here - + //_hal->debug->printf_P(PSTR("cont: ch1: %f\tch2: %f\n"),_hal->rc[ch_thrust]->getRadioPosition(), _hal->rc[ch_str]->getRadioPosition()); // neglects heading command derivative float steering = pidStr.update(_guide->getHeadingError(), -_nav->getYawRate(), dt); - _strCmd = steering; + float thrust = pidThrust.update( + _guide->getGroundSpeedCommand() + - _nav->getGroundSpeed(), dt); - // insert sail command calculation based on sensor position here - _sailCmd = 0; + // obstacle avoidance overrides + // try to drive around the obstacle in front. if this fails, stop + if (_rangeFinderFront) { + _rangeFinderFront->read(); + + int distanceToObstacle = _rangeFinderFront->distance; + if (distanceToObstacle < 100) { + thrust = 0; // Avoidance didn't work out. Stopping + } + else if (distanceToObstacle < 650) { + // Deviating from the course. Deviation angle is inverse proportional + // to the distance to the obstacle, with 15 degrees min angle, 180 - max + steering += (15 + 165 * + (1 - ((float)(distanceToObstacle - 100)) / 550)) * deg2Rad; + } + } + + _strCmd = steering; + _thrustCmd = thrust; } void setMotors() { _hal->rc[ch_str]->setPosition(_strCmd); - _hal->rc[ch_sail]->setPosition(_sailCmd); + _hal->rc[ch_thrust]->setPosition(fabs(_thrustCmd) < 0.1 ? 0 : _thrustCmd); } void handleFailsafe() { // turn off @@ -61,17 +96,19 @@ private: // attributes enum { - ch_mode = 0, ch_str, ch_sail + ch_mode = 0, ch_str, ch_thrust, ch_FwdRev }; enum { - k_chMode = k_radioChannelsStart, k_chStr, k_chSail + k_chMode = k_radioChannelsStart, k_chStr, k_chThrust, k_chFwdRev }; enum { - k_pidStr = k_controllersStart + k_pidStr = k_controllersStart, k_pidThrust }; BlockPIDDfb pidStr; - float _strCmd; - float _sailCmd; + BlockPID pidThrust; + float _strCmd, _thrustCmd; + + RangeFinder * _rangeFinderFront; }; } // namespace apo