001 /*----------------------------------------------------------------------------*/ 002 /* Copyright (c) FIRST 2008-2012. All Rights Reserved. */ 003 /* Open Source Software - may be modified and shared by FRC teams. The code */ 004 /* must be accompanied by the FIRST BSD license file in the root directory of */ 005 /* the project. */ 006 /*----------------------------------------------------------------------------*/ 007 package edu.wpi.first.wpilibj; 008 009 import edu.wpi.first.wpilibj.fpga.tWatchdog; 010 import edu.wpi.first.wpilibj.parsing.IUtility; 011 012 /** 013 * Watchdog timer class. 014 * The watchdog timer is designed to keep the robots safe. The idea is that the robot program must 015 * constantly "feed" the watchdog otherwise it will shut down all the motor outputs. That way if a 016 * program breaks, rather than having the robot continue to operate at the last known speed, the 017 * motors will be shut down. 018 * 019 * This is serious business. Don't just disable the watchdog. You can't afford it! 020 * 021 * http://thedailywtf.com/Articles/_0x2f__0x2f_TODO_0x3a__Uncomment_Later.aspx 022 */ 023 public class Watchdog extends SensorBase implements IUtility{ 024 025 private static Watchdog m_instance; 026 private tWatchdog m_fpgaWatchdog; 027 /** 028 * Default expiration for the watchdog in seconds 029 */ 030 public static final double kDefaultWatchdogExpiration = .5; 031 032 /** 033 * The Watchdog is born. 034 */ 035 protected Watchdog() { 036 m_fpgaWatchdog = new tWatchdog(); 037 setExpiration(Watchdog.kDefaultWatchdogExpiration); 038 setEnabled(true); 039 } 040 041 /** 042 * Get an instance of the watchdog 043 * @return an instance of the watchdog 044 */ 045 public static synchronized Watchdog getInstance() { 046 if (m_instance == null) { 047 m_instance = new Watchdog(); 048 } 049 return m_instance; 050 } 051 052 /** 053 * Throw the dog a bone. 054 * 055 * When everything is going well, you feed your dog when you get home. 056 * Let's hope you don't drive your car off a bridge on the way home... 057 * Your dog won't get fed and he will starve to death. 058 * 059 * By the way, it's not cool to ask the neighbor (some random task) to 060 * feed your dog for you. He's your responsibility! 061 */ 062 public void feed() { 063 tWatchdog.strobeFeed(); 064 } 065 066 /** 067 * Put the watchdog out of its misery. 068 * 069 * Don't wait for your dying robot to starve when there is a problem. 070 * Kill it quickly, cleanly, and humanely. 071 */ 072 public void kill() { 073 tWatchdog.strobeKill(); 074 } 075 076 /** 077 * Read how long it has been since the watchdog was last fed. 078 * 079 * @return The number of seconds since last meal. 080 */ 081 public double getTimer() { 082 long timer = tWatchdog.readTimer(); 083 return timer / (kSystemClockTicksPerMicrosecond * 1e6); 084 } 085 086 /** 087 * Read what the current expiration is. 088 * 089 * @return The number of seconds before starvation following a meal (watchdog starves if it doesn't eat this often). 090 */ 091 public double getExpiration() { 092 long expiration = tWatchdog.readExpiration(); 093 return (double)expiration / (kSystemClockTicksPerMicrosecond * 1e6); 094 } 095 096 /** 097 * Configure how many seconds your watchdog can be neglected before it starves to death. 098 * 099 * @param expiration The number of seconds before starvation following a meal (watchdog starves if it doesn't eat this often). 100 */ 101 public void setExpiration(double expiration) { 102 tWatchdog.writeExpiration((int) (expiration * (kSystemClockTicksPerMicrosecond * 1e6))); 103 } 104 105 /** 106 * Find out if the watchdog is currently enabled or disabled (mortal or immortal). 107 * 108 * @return Enabled or disabled. 109 */ 110 public boolean getEnabled() { 111 return !tWatchdog.readImmortal(); 112 } 113 114 /** 115 * Enable or disable the watchdog timer. 116 * 117 * When enabled, you must keep feeding the watchdog timer to 118 * keep the watchdog active, and hence the dangerous parts 119 * (motor outputs, etc.) can keep functioning. 120 * When disabled, the watchdog is immortal and will remain active 121 * even without being fed. It will also ignore any kill commands 122 * while disabled. 123 * 124 * @param enabled Enable or disable the watchdog. 125 */ 126 public void setEnabled(final boolean enabled) { 127 tWatchdog.writeImmortal(!enabled); 128 } 129 130 /** 131 * Check in on the watchdog and make sure he's still kicking. 132 * 133 * This indicates that your watchdog is allowing the system to operate. 134 * It is still possible that the network communications is not allowing the 135 * system to run, but you can check this to make sure it's not your fault. 136 * Check isSystemActive() for overall system status. 137 * 138 * If the watchdog is disabled, then your watchdog is immortal. 139 * 140 * @return Is the watchdog still alive? 141 */ 142 public boolean isAlive() { 143 return tWatchdog.readStatus_Alive(); 144 } 145 146 /** 147 * Check on the overall status of the system. 148 * 149 * @return Is the system active (i.e. PWM motor outputs, etc. enabled)? 150 */ 151 public boolean isSystemActive() { 152 return tWatchdog.readStatus_SystemActive(); 153 } 154 }