// Copyright (c) FIRST and other WPILib contributors. // Open Source Software; you can modify and/or share it under the terms of // the WPILib BSD license file in the root directory of this project. #include "frc/MotorSafety.h" #include #include #include #include "frc/DriverStation.h" #include "frc/Errors.h" using namespace frc; static wpi::SmallPtrSet instanceList; static wpi::mutex listMutex; MotorSafety::MotorSafety() { std::scoped_lock lock(listMutex); instanceList.insert(this); } MotorSafety::~MotorSafety() { std::scoped_lock lock(listMutex); instanceList.erase(this); } MotorSafety::MotorSafety(MotorSafety&& rhs) : m_expiration(std::move(rhs.m_expiration)), m_enabled(std::move(rhs.m_enabled)), m_stopTime(std::move(rhs.m_stopTime)) {} MotorSafety& MotorSafety::operator=(MotorSafety&& rhs) { std::scoped_lock lock(m_thisMutex, rhs.m_thisMutex); m_expiration = std::move(rhs.m_expiration); m_enabled = std::move(rhs.m_enabled); m_stopTime = std::move(rhs.m_stopTime); return *this; } void MotorSafety::Feed() { std::scoped_lock lock(m_thisMutex); m_stopTime = Timer::GetFPGATimestamp() + m_expiration; } void MotorSafety::SetExpiration(units::second_t expirationTime) { std::scoped_lock lock(m_thisMutex); m_expiration = expirationTime; } units::second_t MotorSafety::GetExpiration() const { std::scoped_lock lock(m_thisMutex); return m_expiration; } bool MotorSafety::IsAlive() const { std::scoped_lock lock(m_thisMutex); return !m_enabled || m_stopTime > Timer::GetFPGATimestamp(); } void MotorSafety::SetSafetyEnabled(bool enabled) { std::scoped_lock lock(m_thisMutex); m_enabled = enabled; } bool MotorSafety::IsSafetyEnabled() const { std::scoped_lock lock(m_thisMutex); return m_enabled; } void MotorSafety::Check() { bool enabled; units::second_t stopTime; { std::scoped_lock lock(m_thisMutex); enabled = m_enabled; stopTime = m_stopTime; } DriverStation& ds = DriverStation::GetInstance(); if (!enabled || ds.IsDisabled() || ds.IsTest()) { return; } if (stopTime < Timer::GetFPGATimestamp()) { FRC_ReportError(err::Timeout, "{}... Output not updated often enough", GetDescription()); StopMotor(); } } void MotorSafety::CheckMotors() { std::scoped_lock lock(listMutex); for (auto elem : instanceList) { elem->Check(); } }