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 }