<commit_before>/*=====================================================================
QGroundControl Open Source Ground Control Station

(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

This file is part of the QGROUNDCONTROL project

    QGROUNDCONTROL is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    QGROUNDCONTROL is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

======================================================================*/

/**
 * @file
 *   @brief Implementation of class MainWindow
 *   @author Your Name here
 */

#include "ArduPilotMegaMAV.h"
#include "QsLog.h"
#include "GAudioOutput.h"

#ifndef MAVLINK_MSG_ID_MOUNT_CONFIGURE
#include "ardupilotmega/mavlink_msg_mount_configure.h"
#endif

#ifndef MAVLINK_MSG_ID_MOUNT_CONTROL
#include "ardupilotmega/mavlink_msg_mount_control.h"
#endif

#include <QString>
#include <QDir>
#include <QDesktopServices>

CustomMode::CustomMode()
{
}

CustomMode::CustomMode(int aMode)
{
    m_mode = aMode;
}

int CustomMode::modeAsInt()
{
    return m_mode;
}

QString CustomMode::operator <<(int aMode)
{
    return QString::number(aMode);
}

ApmPlane::ApmPlane(planeMode aMode)
{
    CustomMode(static_cast<int>(aMode));
}

ApmPlane::planeMode ApmPlane::mode()
{
    return static_cast<ApmPlane::planeMode>(m_mode);
}

QString ApmPlane::stringForMode(int aMode)
{
    switch(static_cast<planeMode>(aMode)) {
    case MANUAL:
        return "Manual";
        break;
    case CIRCLE:
        return "Circle";
        break;
    case STABILIZE:
        return "Stabilize";
        break;
    case TRAINING:
        return "Training";
        break;
    case FLY_BY_WIRE_A:
        return "Fly-By-Wire B";
        break;
    case FLY_BY_WIRE_B:
        return "Fly-By-Wire B";
        break;
    case AUTO:
        return "Auto";
        break;
    case RTL:
        return "Return to Launch";
        break;
    case LOITER:
        return "Loiter";
        break;
    case GUIDED:
        return "Guided";
        break;
    case INITIALIZING:
        return "Initializing";
        break;
    default:
        return "Undefined";
    }
}

ApmCopter::ApmCopter(copterMode aMode)
{
     CustomMode(static_cast<int>(aMode));
}

ApmCopter::copterMode ApmCopter::mode()
{
    return static_cast<ApmCopter::copterMode>(m_mode);
}

QString ApmCopter::stringForMode(int aMode) {
    switch(static_cast<copterMode>(aMode)) {
    case STABILIZE:
        return "Stabilize";
        break;
    case ACRO:
        return "Acro";
        break;
    case ALT_HOLD:
        return "Altitude Hold";
        break;
    case AUTO:
        return "Auto";
        break;
    case GUIDED:
        return "Guided";
        break;
    case LOITER:
        return "Loiter";
        break;
    case RTL:
        return "Return to Launch";
        break;
    case CIRCLE:
        return "Circle";
        break;
    case POSITION:
        return "Position";
        break;
    case LAND:
        return "Land";
        break;
    case OF_LOITER:
        return "OF Loiter";
        break;
    case TOY_A:
        return "Toy A";
        break;
    case TOY_M:
        return "Toy M";
        break;
    case SPORT:
        return "Sport";
        break;
    default:
        return "Undefined";
    }
}

ApmRover::ApmRover(roverMode aMode)
{
     CustomMode(static_cast<int>(aMode));
}

ApmRover::roverMode ApmRover::mode()
{
    return static_cast<ApmRover::roverMode>(m_mode);
}

QString ApmRover::stringForMode(int aMode) {
    switch(static_cast<roverMode>(aMode)) {
    case MANUAL:
        return "Manual";
        break;
    case LEARNING:
        return "Learning";
        break;
    case STEERING:
        return "Steering";
        break;
    case HOLD:
        return "Hold";
        break;
    case AUTO:
        return "Auto";
        break;
    case RTL:
        return "Return to Launch";
        break;
    case GUIDED:
        return "Guided";
        break;
    case INITIALIZING:
        return "Initializing";
        break;
    default:
        return "Undefined";
    }
}

ArduPilotMegaMAV::ArduPilotMegaMAV(MAVLinkProtocol* mavlink, int id) :
    UAS(mavlink, id)//,
    // place other initializers here
{
    //This does not seem to work. Manually request each stream type at a specified rate.
    // Ask for all streams at 4 Hz
    //enableAllDataTransmission(4);
    txReqTimer = new QTimer(this);
    connect(txReqTimer,SIGNAL(timeout()),this,SLOT(RequestAllDataStreams()));

    QTimer::singleShot(5000,this,SLOT(RequestAllDataStreams())); //Send an initial TX request in 5 seconds.

    txReqTimer->start(10000); //Resend the TX requests every 10 seconds.

    connect(this,SIGNAL(connected()),this,SLOT(uasConnected()));
    connect(this,SIGNAL(disconnected()),this,SLOT(uasDisconnected()));

    connect(this, SIGNAL(textMessageReceived(int,int,int,QString)),
            this, SLOT(textMessageReceived(int,int,int,QString)));

    connect(this, SIGNAL(heartbeatTimeout(bool,uint)),
            this, SLOT(heartbeatTimeout(bool,uint)));
}

void ArduPilotMegaMAV::RequestAllDataStreams()
{
    QLOG_TRACE() << "APM:RequestAllDataRates";
    enableExtendedSystemStatusTransmission(2);

    enablePositionTransmission(3);

    enableExtra1Transmission(10);

    enableExtra2Transmission(10);

    enableExtra3Transmission(2);

    enableRawSensorDataTransmission(2);

    enableRCChannelDataTransmission(2);
}

void ArduPilotMegaMAV::uasConnected()
{
    QLOG_INFO() << "ArduPilotMegaMAV APM Connected";
    QTimer::singleShot(500,this,SLOT(RequestAllDataStreams())); //Send an initial TX request in 0.5 seconds.
    createNewMAVLinkLog(type);
}

void ArduPilotMegaMAV::uasDisconnected()
{
    QLOG_INFO() << "ArduPilotMegaMAV APM disconnected";
    mavlink->stopLogging();
}

void ArduPilotMegaMAV::createNewMAVLinkLog(uint8_t type)
{
    QString subDir;

    // This creates a log in subdir based on the vehicle
    // first detected. When connecting to multiple vehicles
    // it will not log message based on each specific.
    switch(type) {
    case MAV_TYPE_TRICOPTER:
        subDir = "/tricopter/";
        break;

    case MAV_TYPE_QUADROTOR:
        subDir = "/quadcopter/";
        break;

    case MAV_TYPE_HEXAROTOR:
        subDir = "/hexcopter/";
        break;

    case MAV_TYPE_OCTOROTOR:
        subDir = "/octocopter/";
        break;

    case MAV_TYPE_GROUND_ROVER:
        subDir = "/rover/";
        break;

    case MAV_TYPE_HELICOPTER:
        subDir = "/helicopter/";
        break;

    case MAV_TYPE_FIXED_WING:
        subDir = "/plane/";
        break;

    default:
        subDir = "/";
    }

    QString logFileName =  QGC::MAVLinkLogDirectory() + QGC::fileNameAsTime();
    QLOG_DEBUG() << "start new MAVLink Log:" << logFileName;
    mavlink->startLogging(logFileName);
}

/**
 * This function is called by MAVLink once a complete, uncorrupted (CRC check valid)
 * mavlink packet is received.
 *
 * @param link Hardware link the message came from (e.g. /dev/ttyUSB0 or UDP port).
 *             messages can be sent back to the system via this link
 * @param message MAVLink message, as received from the MAVLink protocol stack
 */
void ArduPilotMegaMAV::receiveMessage(LinkInterface* link, mavlink_message_t message)
{
    // Let UAS handle the default message set
    UAS::receiveMessage(link, message);

    if (message.sysid == uasId) {
        // Handle your special messages
        switch (message.msgid) {
        case MAVLINK_MSG_ID_HEARTBEAT:
        {
            //QLOG_DEBUG() << "ARDUPILOT RECEIVED HEARTBEAT";
            break;
        }
        default:
            //QLOG_DEBUG() << "\nARDUPILOT RECEIVED MESSAGE WITH ID" << message.msgid;
            break;
        }
    }
}
void ArduPilotMegaMAV::setMountConfigure(unsigned char mode, bool stabilize_roll,bool stabilize_pitch,bool stabilize_yaw)
{
    //Only supported by APM
    mavlink_message_t msg;
    mavlink_msg_mount_configure_pack(255,1,&msg,this->uasId,1,mode,stabilize_roll,stabilize_pitch,stabilize_yaw);
    sendMessage(msg);
}
void ArduPilotMegaMAV::setMountControl(double pa,double pb,double pc,bool islatlong)
{
    mavlink_message_t msg;
    if (islatlong)
    {
        mavlink_msg_mount_control_pack(255,1,&msg,this->uasId,1,pa*10000000.0,pb*10000000.0,pc*10000000.0,0);
    }
    else
    {
        mavlink_msg_mount_control_pack(255,1,&msg,this->uasId,1,pa,pb,pc,0);
    }
    sendMessage(msg);
}

void ArduPilotMegaMAV::armSystem()
{
    QLOG_INFO() << "APM ARM System";
    mavlink_message_t msg;
    mavlink_msg_command_long_pack(mavlink->getSystemId(),
                                  mavlink->getComponentId(),
                                  &msg,
                                  getUASID(),                    // uint8_t target_system,
                                  MAV_COMP_ID_SYSTEM_CONTROL,    // uint8_t target_component
                                  MAV_CMD_COMPONENT_ARM_DISARM,    // uint16_t command,
                                  1,                // uint8_t confirmation,
                                  1.0,             // float param1,
                                  0,                // float param2,
                                  0,                // float param3,
                                  0,                // float param4,
                                  0,                // float param5,
                                  0,                // float param6,
                                  0                 // float param7)
                                  );
    sendMessage(msg);
}

void ArduPilotMegaMAV::disarmSystem()
{
    QLOG_INFO() << "APM DISARM System";
    mavlink_message_t msg;
    mavlink_msg_command_long_pack(mavlink->getSystemId(),
                                  mavlink->getComponentId(),
                                  &msg,
                                  getUASID(),                    // uint8_t target_system,
                                  MAV_COMP_ID_SYSTEM_CONTROL,    // uint8_t target_component
                                  MAV_CMD_COMPONENT_ARM_DISARM,    // uint16_t command,
                                  1,                // uint8_t confirmation,
                                  0.0,             // float param1,
                                  0,                // float param2,
                                  0,                // float param3,
                                  0,                // float param4,
                                  0,                // float param5,
                                  0,                // float param6,
                                  0                 // float param7)
                                  );
    sendMessage(msg);
}

QString ArduPilotMegaMAV::getCustomModeText()
{
    QLOG_DEBUG() << "APM: getCustomModeText()";
    QString customModeString;

    int systemType = getSystemType();
            switch(systemType) {
        case MAV_TYPE_FIXED_WING:
            customModeString = ApmPlane::stringForMode(custom_mode);
            break;

        case MAV_TYPE_QUADROTOR:
        case MAV_TYPE_OCTOROTOR:
        case MAV_TYPE_HELICOPTER:
        case MAV_TYPE_TRICOPTER:
            customModeString = ApmCopter::stringForMode(custom_mode);
            break;

        case MAV_TYPE_GROUND_ROVER:
            customModeString = ApmCopter::stringForMode(custom_mode);
            break;

        default:
            QLOG_WARN() << "APM: Unsupported System Type " << systemType;
            customModeString = tr("APM UNKOWN");
        }
    return customModeString;
}

QString ArduPilotMegaMAV::getCustomModeAudioText()
{
    QLOG_DEBUG() << "APM: getCustomModeAudioText()";

    QString returnString = tr("and mode is ");
    return returnString + getCustomModeText();
}

void ArduPilotMegaMAV::textMessageReceived(int /*uasid*/, int /*componentid*/, int severity, QString text)
{
    QLOG_DEBUG() << "APM: Text Message rx'd" << text;
    if (text.startsWith("PreArm:")) {
        // Speak the PreArm warning
        QString audioString = "Pre-arm check:" + text.remove("PreArm:");
        GAudioOutput::instance()->say(audioString, severity);
    } else if (text.startsWith("Arm:")){
        QString audioString = "Please press and hold safety switch";
        GAudioOutput::instance()->say(audioString, severity);
    }
}

void ArduPilotMegaMAV::heartbeatTimeout(bool timeout, unsigned int /*ms*/)
{
    if(timeout == false) {
        QLOG_DEBUG() << "Send requestall data streams when heartbeat restarts";
        // Request data, as this means we have reconnected
        // Send an request in .5 seconds.
        QTimer::singleShot(500,this,SLOT(RequestAllDataStreams()));
    }
}

void ArduPilotMegaMAV::playCustomModeChangedAudioMessage()
{
    QString phrase;

    phrase = "Mode changed to " + getCustomModeText() + " for system " + QString::number(getUASID());
    QLOG_DEBUG() << "APM say:" << phrase;
    GAudioOutput::instance()->say(phrase.toLower());
}

void ArduPilotMegaMAV::playArmStateChangedAudioMessage(bool armedState)
{
    QString armedPhrase("disarmed");

    if (armedState){
        armedPhrase = "armed";
    }

    QLOG_DEBUG() << "APM say:" << armedPhrase;
    GAudioOutput::instance()->say(QString("system %1 is %2").arg(QString::number(getUASID()),armedPhrase));
}

<commit_msg>Typo for Fly-By-Wire A reported as B for APM:Plane<commit_after>/*=====================================================================
QGroundControl Open Source Ground Control Station

(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

This file is part of the QGROUNDCONTROL project

    QGROUNDCONTROL is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    QGROUNDCONTROL is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

======================================================================*/

/**
 * @file
 *   @brief Implementation of class MainWindow
 *   @author Your Name here
 */

#include "ArduPilotMegaMAV.h"
#include "QsLog.h"
#include "GAudioOutput.h"

#ifndef MAVLINK_MSG_ID_MOUNT_CONFIGURE
#include "ardupilotmega/mavlink_msg_mount_configure.h"
#endif

#ifndef MAVLINK_MSG_ID_MOUNT_CONTROL
#include "ardupilotmega/mavlink_msg_mount_control.h"
#endif

#include <QString>
#include <QDir>
#include <QDesktopServices>

CustomMode::CustomMode()
{
}

CustomMode::CustomMode(int aMode)
{
    m_mode = aMode;
}

int CustomMode::modeAsInt()
{
    return m_mode;
}

QString CustomMode::operator <<(int aMode)
{
    return QString::number(aMode);
}

ApmPlane::ApmPlane(planeMode aMode)
{
    CustomMode(static_cast<int>(aMode));
}

ApmPlane::planeMode ApmPlane::mode()
{
    return static_cast<ApmPlane::planeMode>(m_mode);
}

QString ApmPlane::stringForMode(int aMode)
{
    switch(static_cast<planeMode>(aMode)) {
    case MANUAL:
        return "Manual";
        break;
    case CIRCLE:
        return "Circle";
        break;
    case STABILIZE:
        return "Stabilize";
        break;
    case TRAINING:
        return "Training";
        break;
    case FLY_BY_WIRE_A:
        return "Fly-By-Wire A";
        break;
    case FLY_BY_WIRE_B:
        return "Fly-By-Wire B";
        break;
    case AUTO:
        return "Auto";
        break;
    case RTL:
        return "Return to Launch";
        break;
    case LOITER:
        return "Loiter";
        break;
    case GUIDED:
        return "Guided";
        break;
    case INITIALIZING:
        return "Initializing";
        break;
    default:
        return "Undefined";
    }
}

ApmCopter::ApmCopter(copterMode aMode)
{
     CustomMode(static_cast<int>(aMode));
}

ApmCopter::copterMode ApmCopter::mode()
{
    return static_cast<ApmCopter::copterMode>(m_mode);
}

QString ApmCopter::stringForMode(int aMode) {
    switch(static_cast<copterMode>(aMode)) {
    case STABILIZE:
        return "Stabilize";
        break;
    case ACRO:
        return "Acro";
        break;
    case ALT_HOLD:
        return "Altitude Hold";
        break;
    case AUTO:
        return "Auto";
        break;
    case GUIDED:
        return "Guided";
        break;
    case LOITER:
        return "Loiter";
        break;
    case RTL:
        return "Return to Launch";
        break;
    case CIRCLE:
        return "Circle";
        break;
    case POSITION:
        return "Position";
        break;
    case LAND:
        return "Land";
        break;
    case OF_LOITER:
        return "OF Loiter";
        break;
    case TOY_A:
        return "Toy A";
        break;
    case TOY_M:
        return "Toy M";
        break;
    case SPORT:
        return "Sport";
        break;
    default:
        return "Undefined";
    }
}

ApmRover::ApmRover(roverMode aMode)
{
     CustomMode(static_cast<int>(aMode));
}

ApmRover::roverMode ApmRover::mode()
{
    return static_cast<ApmRover::roverMode>(m_mode);
}

QString ApmRover::stringForMode(int aMode) {
    switch(static_cast<roverMode>(aMode)) {
    case MANUAL:
        return "Manual";
        break;
    case LEARNING:
        return "Learning";
        break;
    case STEERING:
        return "Steering";
        break;
    case HOLD:
        return "Hold";
        break;
    case AUTO:
        return "Auto";
        break;
    case RTL:
        return "Return to Launch";
        break;
    case GUIDED:
        return "Guided";
        break;
    case INITIALIZING:
        return "Initializing";
        break;
    default:
        return "Undefined";
    }
}

ArduPilotMegaMAV::ArduPilotMegaMAV(MAVLinkProtocol* mavlink, int id) :
    UAS(mavlink, id)//,
    // place other initializers here
{
    //This does not seem to work. Manually request each stream type at a specified rate.
    // Ask for all streams at 4 Hz
    //enableAllDataTransmission(4);
    txReqTimer = new QTimer(this);
    connect(txReqTimer,SIGNAL(timeout()),this,SLOT(RequestAllDataStreams()));

    QTimer::singleShot(5000,this,SLOT(RequestAllDataStreams())); //Send an initial TX request in 5 seconds.

    txReqTimer->start(10000); //Resend the TX requests every 10 seconds.

    connect(this,SIGNAL(connected()),this,SLOT(uasConnected()));
    connect(this,SIGNAL(disconnected()),this,SLOT(uasDisconnected()));

    connect(this, SIGNAL(textMessageReceived(int,int,int,QString)),
            this, SLOT(textMessageReceived(int,int,int,QString)));

    connect(this, SIGNAL(heartbeatTimeout(bool,uint)),
            this, SLOT(heartbeatTimeout(bool,uint)));
}

void ArduPilotMegaMAV::RequestAllDataStreams()
{
    QLOG_TRACE() << "APM:RequestAllDataRates";
    enableExtendedSystemStatusTransmission(2);

    enablePositionTransmission(3);

    enableExtra1Transmission(10);

    enableExtra2Transmission(10);

    enableExtra3Transmission(2);

    enableRawSensorDataTransmission(2);

    enableRCChannelDataTransmission(2);
}

void ArduPilotMegaMAV::uasConnected()
{
    QLOG_INFO() << "ArduPilotMegaMAV APM Connected";
    QTimer::singleShot(500,this,SLOT(RequestAllDataStreams())); //Send an initial TX request in 0.5 seconds.
    createNewMAVLinkLog(type);
}

void ArduPilotMegaMAV::uasDisconnected()
{
    QLOG_INFO() << "ArduPilotMegaMAV APM disconnected";
    mavlink->stopLogging();
}

void ArduPilotMegaMAV::createNewMAVLinkLog(uint8_t type)
{
    QString subDir;

    // This creates a log in subdir based on the vehicle
    // first detected. When connecting to multiple vehicles
    // it will not log message based on each specific.
    switch(type) {
    case MAV_TYPE_TRICOPTER:
        subDir = "/tricopter/";
        break;

    case MAV_TYPE_QUADROTOR:
        subDir = "/quadcopter/";
        break;

    case MAV_TYPE_HEXAROTOR:
        subDir = "/hexcopter/";
        break;

    case MAV_TYPE_OCTOROTOR:
        subDir = "/octocopter/";
        break;

    case MAV_TYPE_GROUND_ROVER:
        subDir = "/rover/";
        break;

    case MAV_TYPE_HELICOPTER:
        subDir = "/helicopter/";
        break;

    case MAV_TYPE_FIXED_WING:
        subDir = "/plane/";
        break;

    default:
        subDir = "/";
    }

    QString logFileName =  QGC::MAVLinkLogDirectory() + QGC::fileNameAsTime();
    QLOG_DEBUG() << "start new MAVLink Log:" << logFileName;
    mavlink->startLogging(logFileName);
}

/**
 * This function is called by MAVLink once a complete, uncorrupted (CRC check valid)
 * mavlink packet is received.
 *
 * @param link Hardware link the message came from (e.g. /dev/ttyUSB0 or UDP port).
 *             messages can be sent back to the system via this link
 * @param message MAVLink message, as received from the MAVLink protocol stack
 */
void ArduPilotMegaMAV::receiveMessage(LinkInterface* link, mavlink_message_t message)
{
    // Let UAS handle the default message set
    UAS::receiveMessage(link, message);

    if (message.sysid == uasId) {
        // Handle your special messages
        switch (message.msgid) {
        case MAVLINK_MSG_ID_HEARTBEAT:
        {
            //QLOG_DEBUG() << "ARDUPILOT RECEIVED HEARTBEAT";
            break;
        }
        default:
            //QLOG_DEBUG() << "\nARDUPILOT RECEIVED MESSAGE WITH ID" << message.msgid;
            break;
        }
    }
}
void ArduPilotMegaMAV::setMountConfigure(unsigned char mode, bool stabilize_roll,bool stabilize_pitch,bool stabilize_yaw)
{
    //Only supported by APM
    mavlink_message_t msg;
    mavlink_msg_mount_configure_pack(255,1,&msg,this->uasId,1,mode,stabilize_roll,stabilize_pitch,stabilize_yaw);
    sendMessage(msg);
}
void ArduPilotMegaMAV::setMountControl(double pa,double pb,double pc,bool islatlong)
{
    mavlink_message_t msg;
    if (islatlong)
    {
        mavlink_msg_mount_control_pack(255,1,&msg,this->uasId,1,pa*10000000.0,pb*10000000.0,pc*10000000.0,0);
    }
    else
    {
        mavlink_msg_mount_control_pack(255,1,&msg,this->uasId,1,pa,pb,pc,0);
    }
    sendMessage(msg);
}

void ArduPilotMegaMAV::armSystem()
{
    QLOG_INFO() << "APM ARM System";
    mavlink_message_t msg;
    mavlink_msg_command_long_pack(mavlink->getSystemId(),
                                  mavlink->getComponentId(),
                                  &msg,
                                  getUASID(),                    // uint8_t target_system,
                                  MAV_COMP_ID_SYSTEM_CONTROL,    // uint8_t target_component
                                  MAV_CMD_COMPONENT_ARM_DISARM,    // uint16_t command,
                                  1,                // uint8_t confirmation,
                                  1.0,             // float param1,
                                  0,                // float param2,
                                  0,                // float param3,
                                  0,                // float param4,
                                  0,                // float param5,
                                  0,                // float param6,
                                  0                 // float param7)
                                  );
    sendMessage(msg);
}

void ArduPilotMegaMAV::disarmSystem()
{
    QLOG_INFO() << "APM DISARM System";
    mavlink_message_t msg;
    mavlink_msg_command_long_pack(mavlink->getSystemId(),
                                  mavlink->getComponentId(),
                                  &msg,
                                  getUASID(),                    // uint8_t target_system,
                                  MAV_COMP_ID_SYSTEM_CONTROL,    // uint8_t target_component
                                  MAV_CMD_COMPONENT_ARM_DISARM,    // uint16_t command,
                                  1,                // uint8_t confirmation,
                                  0.0,             // float param1,
                                  0,                // float param2,
                                  0,                // float param3,
                                  0,                // float param4,
                                  0,                // float param5,
                                  0,                // float param6,
                                  0                 // float param7)
                                  );
    sendMessage(msg);
}

QString ArduPilotMegaMAV::getCustomModeText()
{
    QLOG_DEBUG() << "APM: getCustomModeText()";
    QString customModeString;

    int systemType = getSystemType();
            switch(systemType) {
        case MAV_TYPE_FIXED_WING:
            customModeString = ApmPlane::stringForMode(custom_mode);
            break;

        case MAV_TYPE_QUADROTOR:
        case MAV_TYPE_OCTOROTOR:
        case MAV_TYPE_HELICOPTER:
        case MAV_TYPE_TRICOPTER:
            customModeString = ApmCopter::stringForMode(custom_mode);
            break;

        case MAV_TYPE_GROUND_ROVER:
            customModeString = ApmCopter::stringForMode(custom_mode);
            break;

        default:
            QLOG_WARN() << "APM: Unsupported System Type " << systemType;
            customModeString = tr("APM UNKOWN");
        }
    return customModeString;
}

QString ArduPilotMegaMAV::getCustomModeAudioText()
{
    QLOG_DEBUG() << "APM: getCustomModeAudioText()";

    QString returnString = tr("and mode is ");
    return returnString + getCustomModeText();
}

void ArduPilotMegaMAV::textMessageReceived(int /*uasid*/, int /*componentid*/, int severity, QString text)
{
    QLOG_DEBUG() << "APM: Text Message rx'd" << text;
    if (text.startsWith("PreArm:")) {
        // Speak the PreArm warning
        QString audioString = "Pre-arm check:" + text.remove("PreArm:");
        GAudioOutput::instance()->say(audioString, severity);
    } else if (text.startsWith("Arm:")){
        QString audioString = "Please press and hold safety switch";
        GAudioOutput::instance()->say(audioString, severity);
    }
}

void ArduPilotMegaMAV::heartbeatTimeout(bool timeout, unsigned int /*ms*/)
{
    if(timeout == false) {
        QLOG_DEBUG() << "Send requestall data streams when heartbeat restarts";
        // Request data, as this means we have reconnected
        // Send an request in .5 seconds.
        QTimer::singleShot(500,this,SLOT(RequestAllDataStreams()));
    }
}

void ArduPilotMegaMAV::playCustomModeChangedAudioMessage()
{
    QString phrase;

    phrase = "Mode changed to " + getCustomModeText() + " for system " + QString::number(getUASID());
    QLOG_DEBUG() << "APM say:" << phrase;
    GAudioOutput::instance()->say(phrase.toLower());
}

void ArduPilotMegaMAV::playArmStateChangedAudioMessage(bool armedState)
{
    QString armedPhrase("disarmed");

    if (armedState){
        armedPhrase = "armed";
    }

    QLOG_DEBUG() << "APM say:" << armedPhrase;
    GAudioOutput::instance()->say(QString("system %1 is %2").arg(QString::number(getUASID()),armedPhrase));
}

<|endoftext|>


<commit_before>#include "vtrc-rpc-channel-c.h"

#include "google/protobuf/service.h"
#include "google/protobuf/descriptor.h"

#include "protocol/vtrc-rpc-lowlevel.pb.h"
#include "protocol/vtrc-rpc-options.pb.h"

#include "vtrc-common/vtrc-connection-iface.h"
#include "vtrc-common/vtrc-call-context.h"
#include "vtrc-common/vtrc-protocol-layer.h"
#include "vtrc-common/vtrc-exception.h"
#include "vtrc-common/vtrc-closure-holder.h"

#include "vtrc-chrono.h"

namespace vtrc { namespace client {

    namespace gpb = google::protobuf;

    namespace {
        typedef vtrc::shared_ptr <
            vtrc_rpc::lowlevel_unit
        > lowlevel_unit_sptr;
        typedef vtrc_rpc::message_info message_info;

        const unsigned direct_call_type = message_info::MESSAGE_CALL;
        const unsigned callback_type    = message_info::MESSAGE_INSERTION_CALL;

    }

    struct rpc_channel_c::impl {

        vtrc::weak_ptr<common::connection_iface> connection_;

        rpc_channel_c *parent_;
        const unsigned mess_type_;
        const bool     disable_wait_;

        impl(vtrc::shared_ptr<common::connection_iface> c,
                              common::rpc_channel::options opts)
            :connection_(c)
            ,mess_type_(select_message_type(opts))
            ,disable_wait_(select_message_wait(opts))
        { }

        unsigned select_message_type (common::rpc_channel::options opts) const
        {
            return (opts & common::rpc_channel::USE_CONTEXT_CALL)
                   ? message_info::MESSAGE_INSERTION_CALL
                   : message_info::MESSAGE_CALL;
        }

        bool select_message_wait (common::rpc_channel::options opts) const
        {
            return (opts & common::rpc_channel::DISABLE_WAIT);
        }

        common::protocol_layer &get_protocol(common::connection_iface_sptr &clk)
        {
            return parent_->get_protocol( *clk );
        }

        void send_message( lowlevel_unit_type &llu,
                     const gpb::MethodDescriptor *method,
                           gpb::RpcController *controller,
                     const gpb::Message *  /*  request  */,
                           gpb::Message *      response,
                           gpb::Closure *      done   )
        {
            common::closure_holder done_holder(done);
            common::connection_iface_sptr clk(connection_.lock( ));

            if( clk.get( ) == NULL ) {
                if( controller )
                    controller->SetFailed( "Connection lost" );
                throw vtrc::common::exception( vtrc_errors::ERR_CHANNEL,
                                               "Connection lost");
            }

            const vtrc_rpc::options &call_opt
                            ( get_protocol( clk ).get_method_options(method) );

            if( disable_wait_ )
                llu.mutable_opt( )->set_wait( false );
            else {
                llu.mutable_opt( )->set_wait( call_opt.wait( ) );
                llu.mutable_opt( )->set_accept_callbacks
                                               ( call_opt.accept_callbacks( ) );
            }

            parent_->configure_message_for( clk, llu );
            uint64_t call_id = llu.id( );

            if( llu.opt( ).wait( ) ) {  /// WAITABLE CALL

                rpc_channel::context_holder ch( &get_protocol( clk ), &llu );
                ch.ctx_->set_call_options( call_opt );
                ch.ctx_->set_done_closure( done );

                parent_->process_waitable_call( call_id, llu, response,
                                                clk, call_opt );

            } else {                    /// NOT WAITABLE CALL
                get_protocol( clk ).call_rpc_method( llu );
            }

        }

    };

    rpc_channel_c::rpc_channel_c( common::connection_iface_sptr c )
        :common::rpc_channel(direct_call_type, callback_type)
        ,impl_(new impl(c, common::rpc_channel::DEFAULT))
    {
        impl_->parent_ = this;
    }

    rpc_channel_c::rpc_channel_c( common::connection_iface_sptr c,
                                  common::rpc_channel::options opts )
        :common::rpc_channel(direct_call_type, callback_type)
        ,impl_(new impl(c, opts))
    {
        impl_->parent_ = this;
    }

    rpc_channel_c::~rpc_channel_c( )
    {
        delete impl_;
    }

    void rpc_channel_c::configure_message_for(common::connection_iface_sptr c,
                            common::rpc_channel::lowlevel_unit_type &llu) const
    {
        configure_message( c, impl_->mess_type_, llu );
    }

    void rpc_channel_c::send_message( lowlevel_unit_type &llu,
                                const gpb::MethodDescriptor *method,
                                      gpb::RpcController *controller,
                                const gpb::Message *request,
                                      gpb::Message *response,
                                      gpb::Closure *done)
    {
        impl_->send_message( llu, method, controller, request, response, done );
    }

}}
<commit_msg>examples<commit_after>#include "vtrc-rpc-channel-c.h"

#include "google/protobuf/service.h"
#include "google/protobuf/descriptor.h"

#include "protocol/vtrc-rpc-lowlevel.pb.h"
#include "protocol/vtrc-rpc-options.pb.h"

#include "vtrc-common/vtrc-connection-iface.h"
#include "vtrc-common/vtrc-call-context.h"
#include "vtrc-common/vtrc-protocol-layer.h"
#include "vtrc-common/vtrc-exception.h"
#include "vtrc-common/vtrc-closure-holder.h"

#include "vtrc-chrono.h"

namespace vtrc { namespace client {

    namespace gpb = google::protobuf;

    namespace {
        typedef vtrc::shared_ptr <
            vtrc_rpc::lowlevel_unit
        > lowlevel_unit_sptr;
        typedef vtrc_rpc::message_info message_info;

        const unsigned direct_call_type = message_info::MESSAGE_CALL;
        const unsigned callback_type    = message_info::MESSAGE_INSERTION_CALL;

    }

    struct rpc_channel_c::impl {

        vtrc::weak_ptr<common::connection_iface> connection_;

        rpc_channel_c *parent_;
        const unsigned mess_type_;
        const bool     disable_wait_;

        impl(vtrc::shared_ptr<common::connection_iface> c,
                              common::rpc_channel::options opts)
            :connection_(c)
            ,mess_type_(select_message_type(opts))
            ,disable_wait_(select_message_wait(opts))
        { }

        unsigned select_message_type (common::rpc_channel::options opts) const
        {
            return (opts & common::rpc_channel::USE_CONTEXT_CALL)
                   ? message_info::MESSAGE_INSERTION_CALL
                   : message_info::MESSAGE_CALL;
        }

        bool select_message_wait (common::rpc_channel::options opts) const
        {
            return (opts & common::rpc_channel::DISABLE_WAIT);
        }

        common::protocol_layer &get_protocol(common::connection_iface_sptr &clk)
        {
            return parent_->get_protocol( *clk );
        }

        void send_message( lowlevel_unit_type &llu,
                     const gpb::MethodDescriptor *method,
                           gpb::RpcController    *controller,
                     const gpb::Message          * /*  request  */,
                           gpb::Message          *response,
                           gpb::Closure          *done   )
        {
            common::closure_holder done_holder(done);
            common::connection_iface_sptr clk(connection_.lock( ));

            if( clk.get( ) == NULL ) {
                if( controller )
                    controller->SetFailed( "Connection lost" );
                throw vtrc::common::exception( vtrc_errors::ERR_CHANNEL,
                                               "Connection lost");
            }

            const vtrc_rpc::options &call_opt
                            ( get_protocol( clk ).get_method_options(method) );

            if( disable_wait_ )
                llu.mutable_opt( )->set_wait( false );
            else {
                llu.mutable_opt( )->set_wait( call_opt.wait( ) );
                llu.mutable_opt( )->set_accept_callbacks
                                               ( call_opt.accept_callbacks( ) );
            }

            parent_->configure_message_for( clk, llu );
            uint64_t call_id = llu.id( );

            if( llu.opt( ).wait( ) ) {  /// WAITABLE CALL

                rpc_channel::context_holder ch( &get_protocol( clk ), &llu );
                ch.ctx_->set_call_options( call_opt );
                ch.ctx_->set_done_closure( done );

                parent_->process_waitable_call( call_id, llu, response,
                                                clk, call_opt );

            } else {                    /// NOT WAITABLE CALL
                get_protocol( clk ).call_rpc_method( llu );
            }

        }

    };

    rpc_channel_c::rpc_channel_c( common::connection_iface_sptr c )
        :common::rpc_channel(direct_call_type, callback_type)
        ,impl_(new impl(c, common::rpc_channel::DEFAULT))
    {
        impl_->parent_ = this;
    }

    rpc_channel_c::rpc_channel_c( common::connection_iface_sptr c,
                                  common::rpc_channel::options opts )
        :common::rpc_channel(direct_call_type, callback_type)
        ,impl_(new impl(c, opts))
    {
        impl_->parent_ = this;
    }

    rpc_channel_c::~rpc_channel_c( )
    {
        delete impl_;
    }

    void rpc_channel_c::configure_message_for(common::connection_iface_sptr c,
                            common::rpc_channel::lowlevel_unit_type &llu) const
    {
        configure_message( c, impl_->mess_type_, llu );
    }

    void rpc_channel_c::send_message( lowlevel_unit_type &llu,
                                const gpb::MethodDescriptor *method,
                                      gpb::RpcController *controller,
                                const gpb::Message *request,
                                      gpb::Message *response,
                                      gpb::Closure *done)
    {
        impl_->send_message( llu, method, controller, request, response, done );
    }

}}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"

#include "base/compiler_specific.h"

MSVC_PUSH_WARNING_LEVEL(0);
#include "ContextMenu.h"
#include "Document.h"
#include "DocumentLoader.h"
#include "Editor.h"
#include "EventHandler.h"
#include "FrameLoader.h"
#include "FrameView.h"
#include "HitTestResult.h"
#include "KURL.h"
#include "Widget.h"
MSVC_POP_WARNING();
#undef LOG

#include "webkit/glue/context_menu_client_impl.h"

#include "base/string_util.h"
#include "webkit/glue/context_menu.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webdocumentloader_impl.h"
#include "webkit/glue/webview_impl.h"

#include "base/word_iterator.h"

namespace {

// Helper function to determine whether text is a single word or a sentence.
bool IsASingleWord(const std::wstring& text) {
  WordIterator iter(text, WordIterator::BREAK_WORD);
  int word_count = 0;
  if (!iter.Init()) return false;
  while (iter.Advance()) {
    if (iter.IsWord()) {
      word_count++;
      if (word_count > 1) // More than one word.
        return false;
    }
  }

  // Check for 0 words.
  if (!word_count)
    return false;

  // Has a single word.
  return true;
}

// Helper function to get misspelled word on which context menu
// is to be evolked. This function also sets the word on which context menu
// has been evoked to be the selected word, as required.
std::wstring GetMisspelledWord(const WebCore::ContextMenu* default_menu,
                               WebCore::Frame* selected_frame) {
  std::wstring misspelled_word_string;

  // First select from selectedText to check for multiple word selection.
  misspelled_word_string = CollapseWhitespace(
      webkit_glue::StringToStdWString(selected_frame->selectedText()),
      false);

  // Don't provide suggestions for multiple words.
  if (!misspelled_word_string.empty() &&
      !IsASingleWord(misspelled_word_string))
    return L"";

  WebCore::HitTestResult hit_test_result = selected_frame->eventHandler()->
      hitTestResultAtPoint(default_menu->hitTestResult().point(), true);
  WebCore::Node* inner_node = hit_test_result.innerNode();
  WebCore::VisiblePosition pos(inner_node->renderer()->positionForPoint(
      hit_test_result.localPoint()));

  WebCore::Selection selection;
  if (pos.isNotNull()) {
    selection = WebCore::Selection(pos);
    selection.expandUsingGranularity(WebCore::WordGranularity);
  }

  if (selection.isRange()) {
    selected_frame->setSelectionGranularity(WebCore::WordGranularity);
  }

  if (selected_frame->shouldChangeSelection(selection))
    selected_frame->selection()->setSelection(selection);

  misspelled_word_string = CollapseWhitespace(
      webkit_glue::StringToStdWString(selected_frame->selectedText()),
                                      false);

  return misspelled_word_string;
}

}  // namespace

ContextMenuClientImpl::~ContextMenuClientImpl() {
}

void ContextMenuClientImpl::contextMenuDestroyed() {
  delete this;
}

// Figure out the URL of a page or subframe. Returns |page_type| as the type,
// which indicates page or subframe, or ContextNode::NONE if the URL could not
// be determined for some reason.
static ContextNode GetTypeAndURLFromFrame(WebCore::Frame* frame,
                                          GURL* url,
                                          ContextNode page_node) {
  ContextNode node;
  if (frame) {
    WebCore::DocumentLoader* dl = frame->loader()->documentLoader();
    if (dl) {
      WebDataSource* ds = static_cast<WebDocumentLoaderImpl*>(dl)->
          GetDataSource();
      if (ds) {
        node = page_node;
        *url = ds->HasUnreachableURL() ? ds->GetUnreachableURL()
                                       : ds->GetRequest().GetURL();
      }
    }
  }
  return node;
}

WebCore::PlatformMenuDescription
    ContextMenuClientImpl::getCustomMenuFromDefaultItems(
        WebCore::ContextMenu* default_menu) {
  // Displaying the context menu in this function is a big hack as we don't
  // have context, i.e. whether this is being invoked via a script or in
  // response to user input (Mouse event WM_RBUTTONDOWN,
  // Keyboard events KeyVK_APPS, Shift+F10). Check if this is being invoked
  // in response to the above input events before popping up the context menu.
  if (!webview_->context_menu_allowed())
    return NULL;

  WebCore::HitTestResult r = default_menu->hitTestResult();
  WebCore::Frame* selected_frame = r.innerNonSharedNode()->document()->frame();

  WebCore::IntPoint menu_point =
      selected_frame->view()->contentsToWindow(r.point());

  ContextNode node;

  // Links, Images and Image-Links take preference over all else.
  WebCore::KURL link_url = r.absoluteLinkURL();
  if (!link_url.isEmpty()) {
    node.type |= ContextNode::LINK;
  }
  WebCore::KURL image_url = r.absoluteImageURL();
  if (!image_url.isEmpty()) {
    node.type |= ContextNode::IMAGE;
  }

  // If it's not a link, an image or an image link, show a selection menu or a
  // more generic page menu.
  std::wstring selection_text_string;
  std::wstring misspelled_word_string;
  GURL frame_url;
  GURL page_url;
  std::string security_info;

  std::wstring frame_encoding;
  // Send the frame and page URLs in any case.
  ContextNode frame_node = ContextNode(ContextNode::NONE);
  ContextNode page_node =
      GetTypeAndURLFromFrame(webview_->main_frame()->frame(),
                             &page_url,
                             ContextNode(ContextNode::PAGE));
  if (selected_frame != webview_->main_frame()->frame()) {
    frame_node = GetTypeAndURLFromFrame(selected_frame,
                                        &frame_url,
                                        ContextNode(ContextNode::FRAME));
    frame_encoding = webkit_glue::StringToStdWString(
        selected_frame->loader()->encoding());
  }

  if (r.isSelected()) {
    node.type |= ContextNode::SELECTION;
    selection_text_string = CollapseWhitespace(
      webkit_glue::StringToStdWString(selected_frame->selectedText()),
      false);
  }

  if (r.isContentEditable()) {
    node.type |= ContextNode::EDITABLE;
    if (webview_->GetFocusedWebCoreFrame()->editor()->
        isContinuousSpellCheckingEnabled()) {
      misspelled_word_string = GetMisspelledWord(default_menu,
                                                 selected_frame);
    }
  }

  if (node.type == ContextNode::NONE) {
    if (selected_frame != webview_->main_frame()->frame()) {
      node = frame_node;
    } else {
      node = page_node;
    }
  }

  // Now retrieve the security info.
  WebCore::DocumentLoader* dl = selected_frame->loader()->documentLoader();
  if (dl) {
    WebDataSource* ds = static_cast<WebDocumentLoaderImpl*>(dl)->
        GetDataSource();
    if (ds) {
      const WebResponse& response = ds->GetResponse();
      security_info = response.GetSecurityInfo();
    }
  }

  int edit_flags = ContextNode::CAN_DO_NONE;
  if (webview_->GetFocusedWebCoreFrame()->editor()->canUndo())
    edit_flags |= ContextNode::CAN_UNDO;
  if (webview_->GetFocusedWebCoreFrame()->editor()->canRedo())
    edit_flags |= ContextNode::CAN_REDO;
  if (webview_->GetFocusedWebCoreFrame()->editor()->canCut())
    edit_flags |= ContextNode::CAN_CUT;
  if (webview_->GetFocusedWebCoreFrame()->editor()->canCopy())
    edit_flags |= ContextNode::CAN_COPY;
  if (webview_->GetFocusedWebCoreFrame()->editor()->canPaste())
    edit_flags |= ContextNode::CAN_PASTE;
  if (webview_->GetFocusedWebCoreFrame()->editor()->canDelete())
    edit_flags |= ContextNode::CAN_DELETE;
  // We can always select all...
  edit_flags |= ContextNode::CAN_SELECT_ALL;

  WebViewDelegate* d = webview_->delegate();
  if (d) {
    d->ShowContextMenu(webview_,
                       node,
                       menu_point.x(),
                       menu_point.y(),
                       webkit_glue::KURLToGURL(link_url),
                       webkit_glue::KURLToGURL(image_url),
                       page_url,
                       frame_url,
                       selection_text_string,
                       misspelled_word_string,
                       edit_flags,
                       security_info);
  }
  return NULL;
}

void ContextMenuClientImpl::contextMenuItemSelected(
    WebCore::ContextMenuItem*, const WebCore::ContextMenu*) {
}

void ContextMenuClientImpl::downloadURL(const WebCore::KURL&) {
}

void ContextMenuClientImpl::copyImageToClipboard(const WebCore::HitTestResult&) {
}

void ContextMenuClientImpl::searchWithGoogle(const WebCore::Frame*) {
}

void ContextMenuClientImpl::lookUpInDictionary(WebCore::Frame*) {
}

void ContextMenuClientImpl::speak(const WebCore::String&) {
}

void ContextMenuClientImpl::stopSpeaking() {
}

bool ContextMenuClientImpl::shouldIncludeInspectElementItem() {
    return false;  // TODO(jackson): Eventually include the inspector context menu item
}

#if defined(OS_MACOSX)
void ContextMenuClientImpl::searchWithSpotlight() {
  // TODO(pinkerton): write this
}
#endif
<commit_msg>Fix bug where right click in a text area selects empty space.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"

#include "base/compiler_specific.h"

MSVC_PUSH_WARNING_LEVEL(0);
#include "ContextMenu.h"
#include "Document.h"
#include "DocumentLoader.h"
#include "Editor.h"
#include "EventHandler.h"
#include "FrameLoader.h"
#include "FrameView.h"
#include "HitTestResult.h"
#include "KURL.h"
#include "Widget.h"
MSVC_POP_WARNING();
#undef LOG

#include "webkit/glue/context_menu_client_impl.h"

#include "base/string_util.h"
#include "webkit/glue/context_menu.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webdocumentloader_impl.h"
#include "webkit/glue/webview_impl.h"

#include "base/word_iterator.h"

namespace {

// Helper function to determine whether text is a single word or a sentence.
bool IsASingleWord(const std::wstring& text) {
  WordIterator iter(text, WordIterator::BREAK_WORD);
  int word_count = 0;
  if (!iter.Init()) return false;
  while (iter.Advance()) {
    if (iter.IsWord()) {
      word_count++;
      if (word_count > 1) // More than one word.
        return false;
    }
  }

  // Check for 0 words.
  if (!word_count)
    return false;

  // Has a single word.
  return true;
}

// Helper function to get misspelled word on which context menu
// is to be evolked. This function also sets the word on which context menu
// has been evoked to be the selected word, as required.
std::wstring GetMisspelledWord(const WebCore::ContextMenu* default_menu,
                               WebCore::Frame* selected_frame) {
  std::wstring misspelled_word_string;

  // First select from selectedText to check for multiple word selection.
  misspelled_word_string = CollapseWhitespace(
      webkit_glue::StringToStdWString(selected_frame->selectedText()),
      false);

  // Don't provide suggestions for multiple words.
  if (!misspelled_word_string.empty() &&
      !IsASingleWord(misspelled_word_string))
    return L"";

  WebCore::HitTestResult hit_test_result = selected_frame->eventHandler()->
      hitTestResultAtPoint(default_menu->hitTestResult().point(), true);
  WebCore::Node* inner_node = hit_test_result.innerNode();
  WebCore::VisiblePosition pos(inner_node->renderer()->positionForPoint(
      hit_test_result.localPoint()));

  WebCore::Selection selection;
  if (pos.isNotNull()) {
    selection = WebCore::Selection(pos);
    selection.expandUsingGranularity(WebCore::WordGranularity);
  }

  if (selection.isRange()) {
    selected_frame->setSelectionGranularity(WebCore::WordGranularity);
  }

  if (selected_frame->shouldChangeSelection(selection))
    selected_frame->selection()->setSelection(selection);

  misspelled_word_string = CollapseWhitespace(
      webkit_glue::StringToStdWString(selected_frame->selectedText()),
                                      false);

  // If misspelled word is empty, then that portion should not be selected.
  // Set the selection to that position only, and do not expand.
  if (misspelled_word_string.empty()) {
    selection = WebCore::Selection(pos);
    selected_frame->selection()->setSelection(selection);
  }

  return misspelled_word_string;
}

}  // namespace

ContextMenuClientImpl::~ContextMenuClientImpl() {
}

void ContextMenuClientImpl::contextMenuDestroyed() {
  delete this;
}

// Figure out the URL of a page or subframe. Returns |page_type| as the type,
// which indicates page or subframe, or ContextNode::NONE if the URL could not
// be determined for some reason.
static ContextNode GetTypeAndURLFromFrame(WebCore::Frame* frame,
                                          GURL* url,
                                          ContextNode page_node) {
  ContextNode node;
  if (frame) {
    WebCore::DocumentLoader* dl = frame->loader()->documentLoader();
    if (dl) {
      WebDataSource* ds = static_cast<WebDocumentLoaderImpl*>(dl)->
          GetDataSource();
      if (ds) {
        node = page_node;
        *url = ds->HasUnreachableURL() ? ds->GetUnreachableURL()
                                       : ds->GetRequest().GetURL();
      }
    }
  }
  return node;
}

WebCore::PlatformMenuDescription
    ContextMenuClientImpl::getCustomMenuFromDefaultItems(
        WebCore::ContextMenu* default_menu) {
  // Displaying the context menu in this function is a big hack as we don't
  // have context, i.e. whether this is being invoked via a script or in
  // response to user input (Mouse event WM_RBUTTONDOWN,
  // Keyboard events KeyVK_APPS, Shift+F10). Check if this is being invoked
  // in response to the above input events before popping up the context menu.
  if (!webview_->context_menu_allowed())
    return NULL;

  WebCore::HitTestResult r = default_menu->hitTestResult();
  WebCore::Frame* selected_frame = r.innerNonSharedNode()->document()->frame();

  WebCore::IntPoint menu_point =
      selected_frame->view()->contentsToWindow(r.point());

  ContextNode node;

  // Links, Images and Image-Links take preference over all else.
  WebCore::KURL link_url = r.absoluteLinkURL();
  if (!link_url.isEmpty()) {
    node.type |= ContextNode::LINK;
  }
  WebCore::KURL image_url = r.absoluteImageURL();
  if (!image_url.isEmpty()) {
    node.type |= ContextNode::IMAGE;
  }

  // If it's not a link, an image or an image link, show a selection menu or a
  // more generic page menu.
  std::wstring selection_text_string;
  std::wstring misspelled_word_string;
  GURL frame_url;
  GURL page_url;
  std::string security_info;

  std::wstring frame_encoding;
  // Send the frame and page URLs in any case.
  ContextNode frame_node = ContextNode(ContextNode::NONE);
  ContextNode page_node =
      GetTypeAndURLFromFrame(webview_->main_frame()->frame(),
                             &page_url,
                             ContextNode(ContextNode::PAGE));
  if (selected_frame != webview_->main_frame()->frame()) {
    frame_node = GetTypeAndURLFromFrame(selected_frame,
                                        &frame_url,
                                        ContextNode(ContextNode::FRAME));
    frame_encoding = webkit_glue::StringToStdWString(
        selected_frame->loader()->encoding());
  }

  if (r.isSelected()) {
    node.type |= ContextNode::SELECTION;
    selection_text_string = CollapseWhitespace(
      webkit_glue::StringToStdWString(selected_frame->selectedText()),
      false);
  }

  if (r.isContentEditable()) {
    node.type |= ContextNode::EDITABLE;
    if (webview_->GetFocusedWebCoreFrame()->editor()->
        isContinuousSpellCheckingEnabled()) {
      misspelled_word_string = GetMisspelledWord(default_menu,
                                                 selected_frame);
    }
  }

  if (node.type == ContextNode::NONE) {
    if (selected_frame != webview_->main_frame()->frame()) {
      node = frame_node;
    } else {
      node = page_node;
    }
  }

  // Now retrieve the security info.
  WebCore::DocumentLoader* dl = selected_frame->loader()->documentLoader();
  if (dl) {
    WebDataSource* ds = static_cast<WebDocumentLoaderImpl*>(dl)->
        GetDataSource();
    if (ds) {
      const WebResponse& response = ds->GetResponse();
      security_info = response.GetSecurityInfo();
    }
  }

  int edit_flags = ContextNode::CAN_DO_NONE;
  if (webview_->GetFocusedWebCoreFrame()->editor()->canUndo())
    edit_flags |= ContextNode::CAN_UNDO;
  if (webview_->GetFocusedWebCoreFrame()->editor()->canRedo())
    edit_flags |= ContextNode::CAN_REDO;
  if (webview_->GetFocusedWebCoreFrame()->editor()->canCut())
    edit_flags |= ContextNode::CAN_CUT;
  if (webview_->GetFocusedWebCoreFrame()->editor()->canCopy())
    edit_flags |= ContextNode::CAN_COPY;
  if (webview_->GetFocusedWebCoreFrame()->editor()->canPaste())
    edit_flags |= ContextNode::CAN_PASTE;
  if (webview_->GetFocusedWebCoreFrame()->editor()->canDelete())
    edit_flags |= ContextNode::CAN_DELETE;
  // We can always select all...
  edit_flags |= ContextNode::CAN_SELECT_ALL;

  WebViewDelegate* d = webview_->delegate();
  if (d) {
    d->ShowContextMenu(webview_,
                       node,
                       menu_point.x(),
                       menu_point.y(),
                       webkit_glue::KURLToGURL(link_url),
                       webkit_glue::KURLToGURL(image_url),
                       page_url,
                       frame_url,
                       selection_text_string,
                       misspelled_word_string,
                       edit_flags,
                       security_info);
  }
  return NULL;
}

void ContextMenuClientImpl::contextMenuItemSelected(
    WebCore::ContextMenuItem*, const WebCore::ContextMenu*) {
}

void ContextMenuClientImpl::downloadURL(const WebCore::KURL&) {
}

void ContextMenuClientImpl::copyImageToClipboard(const WebCore::HitTestResult&) {
}

void ContextMenuClientImpl::searchWithGoogle(const WebCore::Frame*) {
}

void ContextMenuClientImpl::lookUpInDictionary(WebCore::Frame*) {
}

void ContextMenuClientImpl::speak(const WebCore::String&) {
}

void ContextMenuClientImpl::stopSpeaking() {
}

bool ContextMenuClientImpl::shouldIncludeInspectElementItem() {
    return false;  // TODO(jackson): Eventually include the inspector context menu item
}

#if defined(OS_MACOSX)
void ContextMenuClientImpl::searchWithSpotlight() {
  // TODO(pinkerton): write this
}
#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <stdio.h>
#include <ctype.h>
#include <cstring>
#include <vector>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
using namespace std;

bool conntest(string x){
    int i = x.size() - 1;
    int y = 0;
    if(x == "&&" || x == ";" || x == "||"){
        //cout << "a" << endl;
        return true;
    }
    else if(x.at(i) == ';' || x.at(i) == '&'
         || x.at(i) == '|')
    {
        return true;
    }
    else if(x.at(y) == ';' || x.at(y) == '|' || x.at(y) == '&'){
        return true;
    }
    else{
        return false;
    }
}

bool endswith(string x){
    int i = x.size() - 1;
    if(x.at(i) == ';' || x.at(i) == '&'
         || x.at(i) == '|')
    {
        return true;
    }
    else{
        return false;
    }
}

int findend(string x){
    for(int i = 0; i < x.size(); i++){
        if(x.at(i) == '&' || x.at(i) == ';'
            || x.at(i) == '|')
        {
            return i;
        }
    }
    return -1;
}

bool beginswith(string x){
    if(x.at(0) == ';' || x.at(0) == '&' || x.at(0) == '|'){
        return true;
    }
    else{
        return false;
    }
}

string chopFront(string x, vector<string> &v){
    if(x.at(0) == '&' && x.at(1) == '&'){
        v.push_back(x.substr(2,x.size()-1));
        return x.substr(0, 2);
    }
    else if(x.at(0) == '|' && x.at(1) == '|'){
        v.push_back(x.substr(2,x.size()-1));
        return x.substr(0, 2);
    }
    else{
        v.push_back(x.substr(1,x.size()-1));
        return x.substr(0, 1);
    }
}

string parse(string x, string& c, vector<string> &v){
    if(x == ";" || x == "||" || x == "&&"){
        c = x;
        return "";
    }
    if(x.at(0) == ';'){
        c = x.at(0);
        v.push_back(x.substr(1,x.size()-1));
        return "";
    }
    else if(x.at(0) == '&' && x.at(1) == '&'){
        c = x.substr(0,1);
        v.push_back(x.substr(2, x.size()-1));
        return "";
    }
    else if(x.at(0) == '|' && x.at(1) == '|'){
        c = x.substr(0,1);
        v.push_back(x.substr(2, x.size()-1));
        return "";
    }
    else if(x.at(x.size()-1) = ';'){
        c = x.at(0);
        return x.substr(0, x.size()-1);
    }
}

bool run(char str[]){
    char* pch;
    bool sucs;
    string connector;
    vector<string> cmd;
    vector<string> addIn;
    pch = strtok(str, " ");

    while(pch != "exit"){
        if(pch == NULL || conntest(pch)){
            if(pch != NULL){
                    string tmp = pch;
                    tmp = parse(tmp, connector, addIn);
                    if(tmp != ""){
                        cmd.push_back(tmp);
                    }
            }
            int pid = fork();
            if(pid == 0){
                char* argc[cmd.size() + 1];
                 for(int i = 0 ; i < cmd.size(); i++ ){
                	 argc[i] = new char[cmd.at(i).size()];
                	 strcpy(argc[i], cmd.at(i).c_str());
                 }
                 argc[cmd.size()] = NULL;
                 if(-1 ==  execvp(argc[0], argc)){
                    perror("execvp");
$ execvp: No such file or directory
$
                 }
            }
            else{
                wait(NULL);
	            pch = strtok(NULL, " ");
	            cmd.clear();
                for(int i = 0; i < addIn.size(); i++){
                    cmd.push_back(addIn.at(i));
                }
                addIn.clear();
	            if(pch == "exit"){
	                exit(1);
                }
                if(pch == NULL && cmd.size() == 0){
	                return true;
                }
            }
       }
       else{
	       if(pch != " "){
               cmd.push_back(pch);
           }
           pch = strtok(NULL, " ");
	       if(pch == "exit"){
	           exit(1);
           }
       }
   }
   return false;
}

int main(){
   bool goon = true;
   while(goon){
       string input;
       cout << "$ ";
       getline(cin, input);
       char str[input.size()+1];
       strcpy(str, input.c_str());
       goon = run(str);
   }
   return 0;
}
<commit_msg>Updated hw0.cpp: allows for more command input cases<commit_after>#include <iostream>
#include <stdio.h>
#include <ctype.h>
#include <cstring>
#include <vector>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
using namespace std;

bool conntest(string x){
    int i = x.size() - 1;
    int y = 0;
    if(x == "&&" || x == ";" || x == "||"){
        return true;
    }
    else if(x.at(i) == ';' || x.at(i) == '&'
         || x.at(i) == '|')
    {
        return true;
    }
    else if(x.at(y) == ';' || x.at(y) == '|' || x.at(y) == '&'){
        return true;
    }
    else{
        for(int i = 0; i < x.size(); i++){
            if(x.at(i) == ';' || x.at(i) == '|' || x.at(i) == '&'){
                return true;
            }
        }
        return false;
    }
}

string parse(string x, string& c, vector<string> &v){
    if(x == ";" || x == "||" || x == "&&"){
        c = x;
        return "";
    }
    if(x.at(0) == ';'){
        c = x.at(0);
        v.push_back(x.substr(1,x.size()-1));
        return "";
    }
    else if(x.at(0) == '&' && x.at(1) == '&'){
        c = x.substr(0,1);
        v.push_back(x.substr(2, x.size()-1));
        return "";
    }
    else if(x.at(0) == '|' && x.at(1) == '|'){
        c = x.substr(0,1);
        v.push_back(x.substr(2, x.size()-1));
        return "";
    }
    else if(x.at(x.size()-1) == ';'){
        c = x.at(0);
        return x.substr(0, x.size()-1);
    }
    else if(x.at(x.size()-2) == '|' && x.at(x.size()-1) == '|'){
        c = x.substr(x.size()-2, x.size()-1);
        return x.substr(0, x.size() - 2) ;
    }
    else if(x.at(x.size()-2) == '&' && x.at(x.size()-1) == '&'){
        c = x.substr(x.size()-2, x.size()-1);
        return x.substr(0, x.size() - 2) ;
    }
    else{
        for(int i = 0; i < x.size(); i++){
            if(x.at(i) == ';' || x.at(i) == '&' || x.at(i) == '|'){
                if(x.at(i) == ';'){
                    c = x.at(i);
                    v.push_back(x.substr(i+1, x.size()-1));
                    return x.substr(0, i);
                }
                else if(i != x.size() - 1 && (x.at(i) == '&' || x.at(i) == '|')){
                    c = x.substr(i, i + 1);
                    v.push_back(x.substr(i+2, x.size() -1));
                    return x.substr(0, i);
                }
            }
        }
    }
}

bool run(char str[]){
    char* pch;
    bool sucs;
    string connector;
    vector<string> cmd;
    vector<string> addIn;
    pch = strtok(str, " ");

    while(pch != "exit"){
        if(pch == NULL || conntest(pch)){
            if(pch != NULL){
                    string tmp = pch;
                    tmp = parse(tmp, connector, addIn);
                    if(tmp != ""){
                        cmd.push_back(tmp);
                    }
            }
            int pid = fork();
            if(pid == 0){
                char* argc[cmd.size() + 1];
                 for(int i = 0 ; i < cmd.size(); i++ ){
                	 argc[i] = new char[cmd.at(i).size()];
                	 strcpy(argc[i], cmd.at(i).c_str());
                 }
                 argc[cmd.size()] = NULL;
                 cout << cmd.at(0) << endl;
                 if(-1 ==  execvp(argc[0], argc)){
                    perror("execvp");
                    return false;
                 }
            }
            else{
                wait(NULL);
	            pch = strtok(NULL, " ");
	            cmd.clear();
                for(int i = 0; i < addIn.size(); i++){
                    cmd.push_back(addIn.at(i));
                }
                addIn.clear();
	            if(pch == "exit"){
	                exit(1);
                }
                if(pch == NULL && cmd.size() == 0){
	                return true;
                }
            }
       }
       else{
	       if(pch != " "){
               cmd.push_back(pch);
           }
           pch = strtok(NULL, " ");
	       if(pch == "exit"){
	           exit(1);
           }
       }
   }
   return false;
}

int main(){
   bool goon = true;
   while(goon){
       string input;
       cout << "$ ";
       getline(cin, input);
       char str[input.size()+1];
       strcpy(str, input.c_str());
       goon = run(str);
   }
   return 0;
}
<|endoftext|>


<commit_before>/*
 * This file is part of the CN24 semantic segmentation software,
 * copyright (C) 2015 Clemens-Alexander Brust (ikosa dot de at gmail dot com).
 *
 * For licensing information, see the LICENSE file included with this project.
 */

#include <iomanip>

#include "Log.h"
#include "GradientTester.h"

#include "NetGraphNode.h"

namespace Conv {

void GradientTester::TestGradient ( NetGraph& graph, unsigned int skip_weights, bool fatal_fail ) {
  const double epsilon = 0.005;
  LOGDEBUG << "Testing gradient. FeedForward...";
	graph.FeedForward();
  LOGDEBUG << "Testing gradient. BackPropagate...";
  graph.BackPropagate();

	const datum initial_loss = graph.AggregateLoss();
	unsigned int global_okay = 0;
	unsigned int global_tolerable = 0;
	unsigned int global_failed = 0;
	unsigned int global_weights = 0;

  LOGDEBUG << "Initial loss: " << initial_loss;
  LOGDEBUG << "Using epsilon: " << epsilon;
  for(unsigned int l = 0; l < graph.GetNodes().size(); l++) {
		NetGraphNode* node = graph.GetNodes()[l];
		Layer* layer = node->layer;
    for(unsigned int p = 0; p < layer->parameters().size(); p++) {
			CombinedTensor* const param = layer->parameters()[p];
      LOGDEBUG << "Testing layer " << l << " (" << layer->GetLayerDescription() << "), parameter set " << p;
      LOGDEBUG << param->data;
      bool passed = true;
      unsigned int okay = 0;
      unsigned int tolerable = 0;
      unsigned int failed = 0;
      unsigned int total = 0;
      for(unsigned int e = 0; e < param->data.elements(); e+=(skip_weights + 1))
      {
        total++;
#ifdef BUILD_OPENCL
	param->data.MoveToCPU();
	param->delta.MoveToCPU();
#endif
	const datum old_param = param->data(e);

	param->data[e] = old_param + epsilon;
	graph.FeedForward();
	const double plus_loss = graph.AggregateLoss();

#ifdef BUILD_OPENCL
	param->data.MoveToCPU();
#endif
	param->data[e] = old_param - epsilon;
graph.FeedForward();
	const double minus_loss = graph.AggregateLoss();

	const double delta = param->delta[e];
	const double actual_delta = (plus_loss - minus_loss) / (2.0 * epsilon);

	const double ratio = actual_delta / delta;
	if(ratio > 1.02 || ratio < 0.98) {
	  if(ratio > 1.2 || ratio < 0.8) {
      if(passed) {
	      LOGWARN << "delta analytic: " << delta << ", numeric: " << actual_delta << ", ratio: " << ratio;
      }
	    passed = false;
	    // std::cout << "!" << std::flush;
			failed++;
	  } else {
	  // std::cout << "#" << std::flush;
		tolerable++;
	  }
	}
	else {
	  // std::cout << "." << std::flush;
	  okay++;
	}
#ifdef BUILD_OPENCL
	param->data.MoveToCPU();
#endif
	param->data[e] = old_param;
      }
      // std::cout << "\n";
      if(passed) {
	LOGDEBUG << "Okay!";
      } else {
	LOGERROR << "Failed!";
      }
			LOGDEBUG << okay << " of " << total << " gradients okay (delta < 2%)";
			LOGDEBUG << tolerable << " of " << total << " gradients tolerable (delta < 20%)";
			LOGDEBUG << failed << " of " << total << " gradients failed (delta >= 20%)";
			global_okay += okay;
			global_tolerable += tolerable;
			global_failed += failed;
			global_weights += total;
    }
  }

	LOGRESULT << global_okay << " of " << global_weights << " tested gradients okay (delta < 2%)" << LOGRESULTEND;
	LOGRESULT << global_tolerable << " of " << global_weights << " tested gradients tolerable (delta < 20%)" << LOGRESULTEND;
	LOGRESULT << global_failed << " of " << global_weights << " tested gradients failed (delta >= 20%)" << LOGRESULTEND;

  if (global_failed > 0 && fatal_fail) {
    FATAL("Failed gradient check!");
  }

}

bool GradientTester::DoGradientTest(Conv::Layer* layer, Conv::Tensor& data, Conv::Tensor& delta, std::vector<Conv::CombinedTensor*>& outputs, Conv::datum epsilon, void (*WriteLossDeltas)(const std::vector<CombinedTensor*>&), datum (*CalculateLoss)(const std::vector<CombinedTensor*>&)) {
  layer->FeedForward();
  WriteLossDeltas(outputs);
  layer->BackPropagate();

  unsigned int elements = data.elements();
  unsigned int okay = 0;

  // Weight gradient test
  for (unsigned int w = 0; w < data.elements(); w++) {
    const Conv::datum weight = data.data_ptr_const()[w];
    const Conv::datum gradient = delta.data_ptr_const()[w];

    // Using central diff
    data.data_ptr()[w] = weight + epsilon;
    layer->FeedForward();
    const Conv::datum forward_loss = CalculateLoss(outputs);

    data.data_ptr()[w] = weight - epsilon;
    layer->FeedForward();
    const Conv::datum backward_loss = CalculateLoss(outputs);

    const Conv::datum fd_gradient = (forward_loss - backward_loss) / (2.0 * epsilon);
    data.data_ptr()[w] = weight;

    const Conv::datum ratio = fd_gradient / gradient;
    if(ratio > 1.2 || ratio < 0.8) {
      LOGDEBUG << "BP Grad : " << gradient;
      LOGDEBUG << "FD Grad : " << fd_gradient;
      LOGDEBUG << "Ratio   : " << ratio;
      LOGDEBUG << "Diff    : " << gradient - fd_gradient;
    } else {
      okay++;
    }
  }
  if(okay != elements) {
    double success_rate = (double)okay/(double)elements;
    if(success_rate > 0.85)
      return true;
    else {
      LOGERROR << okay << " of " << elements << " gradients okay - " << std::setprecision(3) << 100.0 * (double)okay/(double)elements << "%";
      return false;
    }
  } else {
    return true;
  }
}

}
<commit_msg>GradientTester: Fixed missing OpenCL awareness<commit_after>/*
 * This file is part of the CN24 semantic segmentation software,
 * copyright (C) 2015 Clemens-Alexander Brust (ikosa dot de at gmail dot com).
 *
 * For licensing information, see the LICENSE file included with this project.
 */

#include <iomanip>

#include "Log.h"
#include "GradientTester.h"

#include "NetGraphNode.h"

namespace Conv {

void GradientTester::TestGradient ( NetGraph& graph, unsigned int skip_weights, bool fatal_fail ) {
  const double epsilon = 0.005;
  LOGDEBUG << "Testing gradient. FeedForward...";
	graph.FeedForward();
  LOGDEBUG << "Testing gradient. BackPropagate...";
  graph.BackPropagate();

	const datum initial_loss = graph.AggregateLoss();
	unsigned int global_okay = 0;
	unsigned int global_tolerable = 0;
	unsigned int global_failed = 0;
	unsigned int global_weights = 0;

  LOGDEBUG << "Initial loss: " << initial_loss;
  LOGDEBUG << "Using epsilon: " << epsilon;
  for(unsigned int l = 0; l < graph.GetNodes().size(); l++) {
		NetGraphNode* node = graph.GetNodes()[l];
		Layer* layer = node->layer;
    for(unsigned int p = 0; p < layer->parameters().size(); p++) {
			CombinedTensor* const param = layer->parameters()[p];
      LOGDEBUG << "Testing layer " << l << " (" << layer->GetLayerDescription() << "), parameter set " << p;
      LOGDEBUG << param->data;
      bool passed = true;
      unsigned int okay = 0;
      unsigned int tolerable = 0;
      unsigned int failed = 0;
      unsigned int total = 0;
      for(unsigned int e = 0; e < param->data.elements(); e+=(skip_weights + 1))
      {
        total++;
#ifdef BUILD_OPENCL
	param->data.MoveToCPU();
	param->delta.MoveToCPU();
#endif
	const datum old_param = param->data(e);

	param->data[e] = old_param + epsilon;
	graph.FeedForward();
	const double plus_loss = graph.AggregateLoss();

#ifdef BUILD_OPENCL
	param->data.MoveToCPU();
#endif
	param->data[e] = old_param - epsilon;
graph.FeedForward();
	const double minus_loss = graph.AggregateLoss();

	const double delta = param->delta[e];
	const double actual_delta = (plus_loss - minus_loss) / (2.0 * epsilon);

	const double ratio = actual_delta / delta;
	if(ratio > 1.02 || ratio < 0.98) {
	  if(ratio > 1.2 || ratio < 0.8) {
      if(passed) {
	      LOGWARN << "delta analytic: " << delta << ", numeric: " << actual_delta << ", ratio: " << ratio;
      }
	    passed = false;
	    // std::cout << "!" << std::flush;
			failed++;
	  } else {
	  // std::cout << "#" << std::flush;
		tolerable++;
	  }
	}
	else {
	  // std::cout << "." << std::flush;
	  okay++;
	}
#ifdef BUILD_OPENCL
	param->data.MoveToCPU();
#endif
	param->data[e] = old_param;
      }
      // std::cout << "\n";
      if(passed) {
	LOGDEBUG << "Okay!";
      } else {
	LOGERROR << "Failed!";
      }
			LOGDEBUG << okay << " of " << total << " gradients okay (delta < 2%)";
			LOGDEBUG << tolerable << " of " << total << " gradients tolerable (delta < 20%)";
			LOGDEBUG << failed << " of " << total << " gradients failed (delta >= 20%)";
			global_okay += okay;
			global_tolerable += tolerable;
			global_failed += failed;
			global_weights += total;
    }
  }

	LOGRESULT << global_okay << " of " << global_weights << " tested gradients okay (delta < 2%)" << LOGRESULTEND;
	LOGRESULT << global_tolerable << " of " << global_weights << " tested gradients tolerable (delta < 20%)" << LOGRESULTEND;
	LOGRESULT << global_failed << " of " << global_weights << " tested gradients failed (delta >= 20%)" << LOGRESULTEND;

  if (global_failed > 0 && fatal_fail) {
    FATAL("Failed gradient check!");
  }

}

bool GradientTester::DoGradientTest(Conv::Layer* layer, Conv::Tensor& data, Conv::Tensor& delta, std::vector<Conv::CombinedTensor*>& outputs, Conv::datum epsilon, void (*WriteLossDeltas)(const std::vector<CombinedTensor*>&), datum (*CalculateLoss)(const std::vector<CombinedTensor*>&)) {
  layer->FeedForward();
  WriteLossDeltas(outputs);
  layer->BackPropagate();

  unsigned int elements = data.elements();
  unsigned int okay = 0;

  // Weight gradient test
  for (unsigned int w = 0; w < data.elements(); w++) {
#ifdef BUILD_OPENCL
    data.MoveToCPU();
    delta.MoveToCPU();
#endif
    const Conv::datum weight = data.data_ptr_const()[w];
    const Conv::datum gradient = delta.data_ptr_const()[w];

    // Using central diff
    data.data_ptr()[w] = weight + epsilon;
    layer->FeedForward();
    const Conv::datum forward_loss = CalculateLoss(outputs);

#ifdef BUILD_OPENCL
    data.MoveToCPU();
#endif
    data.data_ptr()[w] = weight - epsilon;
    layer->FeedForward();
    const Conv::datum backward_loss = CalculateLoss(outputs);

    const Conv::datum fd_gradient = (forward_loss - backward_loss) / (2.0 * epsilon);

#ifdef BUILD_OPENCL
    data.MoveToCPU();
#endif
    data.data_ptr()[w] = weight;

    const Conv::datum ratio = fd_gradient / gradient;
    if(ratio > 1.2 || ratio < 0.8) {
      LOGDEBUG << "BP Grad : " << gradient;
      LOGDEBUG << "FD Grad : " << fd_gradient;
      LOGDEBUG << "Ratio   : " << ratio;
      LOGDEBUG << "Diff    : " << gradient - fd_gradient;
    } else {
      okay++;
    }
  }
  if(okay != elements) {
    double success_rate = (double)okay/(double)elements;
    if(success_rate > 0.85)
      return true;
    else {
      LOGERROR << okay << " of " << elements << " gradients okay - " << std::setprecision(3) << 100.0 * (double)okay/(double)elements << "%";
      return false;
    }
  } else {
    return true;
  }
}

}
<|endoftext|>