/** * Handler for all exercise objects * $Id$ * $HeadURL$ * $Author$ * Created by Hanna E. Rathje, SLSE, 2015-09-03 */ #include "handler_operating_condition.h" #include "esc_db.h" #include "main_handler.h" #include "handler_vehicle.h" #include "control_unit_handler.h" #include "handler_firing_explosion.h" #include "handler_firing_smoke.h" #include "handler_tab_data.h" #include #include namespace EffectShowClient { //============================================================================= HandlerOperatingCondition::HandlerOperatingCondition(MainHandler *mainHandler, QObject *parent) : QObject(parent) , SendAmmunitionRequestHandler(mainHandler->dds()->fts()) , SendSafetyRevokeRequestHandler(mainHandler->dds()->fts()) , SendReadinessRequestHandler(mainHandler->dds()->fts()) , m_mainHandler(mainHandler) , m_isOperational(false) , m_oldErrorState(false) , m_operationalStatusTimer(new QTimer) , m_logger(getLogger("HandlerOperatingCondition")) {} //============================================================================= HandlerOperatingCondition::~HandlerOperatingCondition() {} //============================================================================= bool HandlerOperatingCondition::init() { m_operatingCondition.readiness(m_isOperational); connect(m_mainHandler->handlerVehicle().get(), &HandlerVehicle::vehicleBattery, this, &HandlerOperatingCondition::onVehicleBattery); connect(m_mainHandler->handlerVehicle().get(), &HandlerVehicle::vehicleSmokeCardridgesFireStatus, this, &HandlerOperatingCondition::onVehicleSmokeCardridgesFireStatus); connect(m_mainHandler->handlerVehicle().get(), &HandlerVehicle::vehicleSmokeCardridgesStatus, this, &HandlerOperatingCondition::onVehicleSmokeCardridgesStatus); connect(m_mainHandler->handlerVehicle().get(), &HandlerVehicle::vehicleFireUnits, this, &HandlerOperatingCondition::onVehicleFireUnits); connect(m_mainHandler->handlerControlUnit().get(), &ControlUnitHandler::safetyWarnings, this, &HandlerOperatingCondition::onSafetyStatus); connect(m_mainHandler->handlerControlUnit().get(), &ControlUnitHandler::vehicleErrorStatus, this, &HandlerOperatingCondition::onVehicleErrorStatus); connect(m_mainHandler->handlerControlUnit().get(), &ControlUnitHandler::vehicleRoundCount, this, &HandlerOperatingCondition::onVehicleRoundCount); connect(m_mainHandler->handlerControlUnit().get(), &ControlUnitHandler::vehicleConnected, this, &HandlerOperatingCondition::onConnectionToSerial); connect(m_mainHandler->handlerControlUnit().get(), &ControlUnitHandler::vehicleFinshedVolley, this, &HandlerOperatingCondition::onVolleyRounds); connect(m_mainHandler->handlerControlUnit().get(), &ControlUnitHandler::vehicleStoppedVolley, this, &HandlerOperatingCondition::onVolleyRounds); connect(m_mainHandler->handlerVehicle().get(), &HandlerVehicle::vehicleType, this, &HandlerOperatingCondition::onVehicleType); connect(m_operationalStatusTimer, &QTimer::timeout, this, &HandlerOperatingCondition::onOperationalStatusTimeout); return true; } void HandlerOperatingCondition::onVehicleBattery(double battery) { m_operatingCondition.batteryVoltage(battery); if (!m_mainHandler->dds()->dts()->publish(m_operatingCondition)) ERROR_LOG(m_logger) << "Error publishing OperatingConditionEntity-data Battery to dds"; } void HandlerOperatingCondition::onVehicleSmokeCardridgesFireStatus(const CardRidges &fireStatus) { int numberOfSmokingCardridgesOld = int(m_smokingCardridges.cardrige1) + int(m_smokingCardridges.cardrige2) + int(m_smokingCardridges.cardrige3) + int(m_smokingCardridges.cardrige4) + int(m_smokingCardridges.cardrige5); //not fireing should be updated in next CardRidgeStatus m_smokingCardridges = fireStatus; int numberOfSmokingCardridgesNew = int(m_smokingCardridges.cardrige1) + int(m_smokingCardridges.cardrige2) + int(m_smokingCardridges.cardrige3) + int(m_smokingCardridges.cardrige4) + int(m_smokingCardridges.cardrige5); int count = numberOfSmokingCardridgesNew - numberOfSmokingCardridgesOld; if (count > 0) { m_operatingCondition.ammunitionAvailable(std::max(0, m_operatingCondition.ammunitionAvailable() - count)); m_operatingCondition.ammunitionMagazine(std::max(0, m_operatingCondition.ammunitionMagazine() - count)); //we are burning now ConvertToTab::VehicleStatus_t vehicleStatus; getVehicleStatus(vehicleStatus); m_mainHandler->handlerFiringSmoke()->setSmoking(); m_mainHandler->handlerTabData()->vehicleStatus(vehicleStatus); } // if if (fireStatus.cardrige1) m_operatingCondition.smokeCartridge1(StatusSmokeCartridge_e_def::Smoking); if (fireStatus.cardrige2) m_operatingCondition.smokeCartridge2(StatusSmokeCartridge_e_def::Smoking); if (fireStatus.cardrige3) m_operatingCondition.smokeCartridge3(StatusSmokeCartridge_e_def::Smoking); if (fireStatus.cardrige4) m_operatingCondition.smokeCartridge4(StatusSmokeCartridge_e_def::Smoking); if (fireStatus.cardrige5) m_operatingCondition.smokeCartridge5(StatusSmokeCartridge_e_def::Smoking); if (!m_mainHandler->dds()->dts()->publish(m_operatingCondition)) ERROR_LOG(m_logger) << "Error publishing OperatingConditionEntity-data (Somoking) to dds"; } void HandlerOperatingCondition::onVehicleSmokeCardridgesStatus(const CardRidges &fireStatus) { m_readyCardridges = fireStatus; if (!m_smokingCardridges.cardrige1) m_operatingCondition.smokeCartridge1(m_readyCardridges.cardrige1 ? StatusSmokeCartridge_e_def::Ready : StatusSmokeCartridge_e_def::NotReady); if (!m_smokingCardridges.cardrige2) m_operatingCondition.smokeCartridge2(m_readyCardridges.cardrige2 ? StatusSmokeCartridge_e_def::Ready : StatusSmokeCartridge_e_def::NotReady); if (!m_smokingCardridges.cardrige3) m_operatingCondition.smokeCartridge3(m_readyCardridges.cardrige3 ? StatusSmokeCartridge_e_def::Ready : StatusSmokeCartridge_e_def::NotReady); if (!m_smokingCardridges.cardrige4) m_operatingCondition.smokeCartridge4(m_readyCardridges.cardrige4 ? StatusSmokeCartridge_e_def::Ready : StatusSmokeCartridge_e_def::NotReady); if (!m_smokingCardridges.cardrige5) m_operatingCondition.smokeCartridge5(m_readyCardridges.cardrige5 ? StatusSmokeCartridge_e_def::Ready : StatusSmokeCartridge_e_def::NotReady); if (!m_mainHandler->dds()->dts()->publish(m_operatingCondition)) ERROR_LOG(m_logger) << "Error publishing OperatingConditionEntity-data to dds"; } void HandlerOperatingCondition::onVehicleFireUnits(const CardRidges &fireStatus) { m_operatingCondition.firingUnitReadyFwdLh(fireStatus.cardrige1); m_operatingCondition.firingUnitReadyFwdRh(fireStatus.cardrige2); m_operatingCondition.firingUnitReadyAftRh(fireStatus.cardrige3); m_operatingCondition.firingUnitReadyAftLh(fireStatus.cardrige4); if (!m_mainHandler->dds()->dts()->publish(m_operatingCondition)) ERROR_LOG(m_logger) << "Error publishing OperatingConditionEntity-data (fireStatus) to dds"; } void HandlerOperatingCondition::onVehicleErrorStatus(const CardRidges &errorStatus) { m_operatingCondition.errorSmoke(errorStatus.cardrige1); m_operatingCondition.errorFireUnit(errorStatus.cardrige2); m_operatingCondition.errorPanel(errorStatus.cardrige3); m_operatingCondition.errorEquipment(errorStatus.cardrige4); m_operatingCondition.errorGeneral(errorStatus.cardrige5); if (!m_mainHandler->dds()->dts()->publish(m_operatingCondition)) ERROR_LOG(m_logger) << "Error publishing OperatingConditionEntity-data (errorStatus) to dds"; if (isErrorDmf() != m_oldErrorState) { m_oldErrorState = isErrorDmf(); ConvertToTab::VehicleStatus_t vehicleStatus; getVehicleStatus(vehicleStatus); m_mainHandler->handlerTabData()->vehicleStatus(vehicleStatus); } } void HandlerOperatingCondition::onOperationalStatusTimeout() { DEBUG_LOG(m_logger) << "Operational status timeout. Setting operational status to: not operational."; m_isOperational = false; m_operatingCondition.readiness(m_isOperational); sendStatus(); } bool HandlerOperatingCondition::isErrorDmf() { return (m_operatingCondition.errorSmoke() || m_operatingCondition.errorFireUnit() || m_operatingCondition.errorPanel() || m_operatingCondition.errorEquipment() || m_operatingCondition.errorGeneral() ); } void HandlerOperatingCondition::onConnectionToSerial() { DEBUG_LOG(m_logger) << "Connected to Serial: send ammunition Magazine to Control Unit Count: " << m_operatingCondition.ammunitionMagazine(); m_mainHandler->handlerVehicle()->setAmmunitionParameter(m_operatingCondition.ammunitionMagazine()); } void HandlerOperatingCondition::onVehicleType(const EffectShowManagement::Feature_e &type) { m_operatingCondition.vehicleFeature(type); if (!m_mainHandler->dds()->dts()->publish(m_operatingCondition)) ERROR_LOG(m_logger) << "Error publishing OperatingConditionEntity-data (vehicle type) to dds"; } void HandlerOperatingCondition::onSafetyStatus(const SafetyStatus &status) { m_operatingCondition.temperatureWarning(status.temperaturWarning); m_operatingCondition.loadingBoardWall(status.loadingBoardWall); m_operatingCondition.emergencyStop(status.emergencyStop); if (!m_mainHandler->dds()->dts()->publish(m_operatingCondition)) ERROR_LOG(m_logger) << "Error publishing OperatingConditionEntity-data (SafetyStatus) to dds"; } void HandlerOperatingCondition::onVehicleRoundCount(int loadedRounds) { DEBUG_LOG(m_logger) << "Got RoundCount Reply from Unit " << loadedRounds; m_operatingCondition.ammunitionMagazine(loadedRounds); if (!m_mainHandler->dds()->dts()->publish(m_operatingCondition)) ERROR_LOG(m_logger) << "Error publishing OperatingConditionEntity-data (ammunition magazine) to dds"; } void HandlerOperatingCondition::onVolleyRounds(int usedRounds) { DEBUG_LOG(m_logger) << "Got used rounds " << usedRounds; m_operatingCondition.ammunitionMagazine(m_operatingCondition.ammunitionMagazine() - usedRounds); if (m_operatingCondition.ammunitionMagazine() < 0) m_operatingCondition.ammunitionMagazine(0); m_operatingCondition.ammunitionAvailable(m_operatingCondition.ammunitionAvailable() - usedRounds); if (m_operatingCondition.ammunitionAvailable() < 0) m_operatingCondition.ammunitionAvailable(0); if (!m_mainHandler->dds()->dts()->publish(m_operatingCondition)) ERROR_LOG(m_logger) << "Error publishing OperatingConditionEntity-data (ammunition magazine used) to dds"; } void HandlerOperatingCondition::sendStatus() { ConvertToTab::VehicleStatus_t vehicleStatus; getVehicleStatus(vehicleStatus); m_mainHandler->handlerTabData()->vehicleStatus(vehicleStatus); } void HandlerOperatingCondition::getVehicleStatus(ConvertToTab::VehicleStatus_t &vehicleStatus) { vehicleStatus.ammunitionAvailable = m_operatingCondition.ammunitionAvailable(); vehicleStatus.ammunitionMagazine = m_operatingCondition.ammunitionMagazine(); vehicleStatus.feature = static_cast(m_operatingCondition.vehicleFeature().underlying()); vehicleStatus.operational = (!m_operatingCondition.errorGeneral() && m_isOperational); vehicleStatus.magazineFail = m_oldErrorState; vehicleStatus.controlComputerFail = m_operatingCondition.errorPanel(); } //----------------------------------------------------------------------------- void HandlerOperatingCondition::onSendAmmunitionRequest(const rti::core::SampleIdentity &cookie, const SendAmmunitionRequest &request) { DEBUG_LOG(m_logger) << "onSendAmmunitionRequest"; //take available ammo and send excon //then wait for reply from unit m_operatingCondition.ammunitionAvailable(request.ammunitionAvailable()); m_mainHandler->dds()->fts()->sendAmmunitionReply(cookie, Core::FunctionReplyObject()); // provision of the control computer with the equipped shots m_mainHandler->handlerVehicle()->setAmmunitionParameter(request.ammunitionMagazine()); // Sending of telegram: DMF-Einsatzbereitschafts-Status to the operating application ConvertToTab::VehicleStatus_t vehicleStatus; getVehicleStatus(vehicleStatus); if (vehicleStatus.feature == EffectShowManagement::Feature_e::Smoke) { //as smoke did not answer vehicleStatus.ammunitionMagazine = request.ammunitionMagazine(); } m_mainHandler->handlerTabData()->vehicleStatus(vehicleStatus); } void HandlerOperatingCondition::onSendSafetyRevokeRequest(const rti::core::SampleIdentity &cookie, const SendSafetyRevokeRequest &request) { DEBUG_LOG(m_logger) << "onSendSafetyRevokeRequest with " << request.revoke(); m_mainHandler->dds()->fts()->sendSafetyRevokeReply(cookie, Core::FunctionReplyObject()); if (request.revoke()) { m_mainHandler->handlerVehicle()->effectShowControl(EffectShowControl_e::StopTimer); m_mainHandler->handlerControlUnit()->send(CommandSignal::FT_SE_CB_SICHERHEIT_WIDERRUFEN); m_mainHandler->handlerFiringExplosion()->onEffectShowInterrupted(); } } void HandlerOperatingCondition::onSendReadinessRequest(const rti::core::SampleIdentity &cookie, const SendReadinessRequest &request) { DEBUG_LOG(m_logger) << "onSendReadinessRequest"; //Confirm or Revoke Readiness //send to EXCON m_isOperational = request.readiness(); m_mainHandler->dds()->fts()->sendReadinessReply(cookie, Core::FunctionReplyObject()); // Sending of telegram: DMF-Einsatzbereitschafts-Status to the operating application ConvertToTab::VehicleStatus_t vehicleStatus; getVehicleStatus(vehicleStatus); m_mainHandler->handlerTabData()->vehicleStatus(vehicleStatus); //now change operating condition in hope that tetra worked m_operatingCondition.readiness(m_isOperational); if (!m_mainHandler->dds()->dts()->publish(m_operatingCondition)) ERROR_LOG(m_logger) << "Error publishing OperatingConditionEntity-data readiness) to dds"; if (m_isOperational) { DEBUG_LOG(m_logger) << "Operating condition: operational. Starting timer."; m_operationalStatusTimer->start(15 * 60 * 1000); } else { DEBUG_LOG(m_logger) << "Operating condition: not operational. Stopping timer."; m_operationalStatusTimer->stop(); } } } // Namespace EffectShowClient