blob: 0a425ba8423ae0c65f5c962d4f4623644f27ab93 [file] [log] [blame]
Brian Silvermanf7f267a2017-02-04 16:16:08 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2008-2017. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include "Servo.h"
9
10#include "LiveWindow/LiveWindow.h"
11
12using namespace frc;
13
14constexpr double Servo::kMaxServoAngle;
15constexpr double Servo::kMinServoAngle;
16
17constexpr double Servo::kDefaultMaxServoPWM;
18constexpr double Servo::kDefaultMinServoPWM;
19
20/**
21 * @param channel The PWM channel to which the servo is attached. 0-9 are
22 * on-board, 10-19 are on the MXP port
23 */
24Servo::Servo(int channel) : SafePWM(channel) {
25 // Set minimum and maximum PWM values supported by the servo
26 SetBounds(kDefaultMaxServoPWM, 0.0, 0.0, 0.0, kDefaultMinServoPWM);
27
28 // Assign defaults for period multiplier for the servo PWM control signal
29 SetPeriodMultiplier(kPeriodMultiplier_4X);
30
31 // std::printf("Done initializing servo %d\n", channel);
32}
33
34Servo::~Servo() {
35 if (m_table != nullptr) {
36 m_table->RemoveTableListener(this);
37 }
38}
39
40/**
41 * Set the servo position.
42 *
43 * Servo values range from 0.0 to 1.0 corresponding to the range of full left to
44 * full right.
45 *
46 * @param value Position from 0.0 to 1.0.
47 */
48void Servo::Set(double value) { SetPosition(value); }
49
50/**
51 * Set the servo to offline.
52 *
53 * Set the servo raw value to 0 (undriven)
54 */
55void Servo::SetOffline() { SetRaw(0); }
56
57/**
58 * Get the servo position.
59 *
60 * Servo values range from 0.0 to 1.0 corresponding to the range of full left to
61 * full right.
62 *
63 * @return Position from 0.0 to 1.0.
64 */
65double Servo::Get() const { return GetPosition(); }
66
67/**
68 * Set the servo angle.
69 *
70 * Assume that the servo angle is linear with respect to the PWM value (big
71 * assumption, need to test).
72 *
73 * Servo angles that are out of the supported range of the servo simply
74 * "saturate" in that direction. In other words, if the servo has a range of
75 * (X degrees to Y degrees) than angles of less than X result in an angle of
76 * X being set and angles of more than Y degrees result in an angle of Y being
77 * set.
78 *
79 * @param degrees The angle in degrees to set the servo.
80 */
81void Servo::SetAngle(double degrees) {
82 if (degrees < kMinServoAngle) {
83 degrees = kMinServoAngle;
84 } else if (degrees > kMaxServoAngle) {
85 degrees = kMaxServoAngle;
86 }
87
88 SetPosition((degrees - kMinServoAngle) / GetServoAngleRange());
89}
90
91/**
92 * Get the servo angle.
93 *
94 * Assume that the servo angle is linear with respect to the PWM value (big
95 * assumption, need to test).
96 *
97 * @return The angle in degrees to which the servo is set.
98 */
99double Servo::GetAngle() const {
100 return GetPosition() * GetServoAngleRange() + kMinServoAngle;
101}
102
103void Servo::ValueChanged(ITable* source, llvm::StringRef key,
104 std::shared_ptr<nt::Value> value, bool isNew) {
105 if (!value->IsDouble()) return;
106 Set(value->GetDouble());
107}
108
109void Servo::UpdateTable() {
110 if (m_table != nullptr) {
111 m_table->PutNumber("Value", Get());
112 }
113}
114
115void Servo::StartLiveWindowMode() {
116 if (m_table != nullptr) {
117 m_table->AddTableListener("Value", this, true);
118 }
119}
120
121void Servo::StopLiveWindowMode() {
122 if (m_table != nullptr) {
123 m_table->RemoveTableListener(this);
124 }
125}
126
127std::string Servo::GetSmartDashboardType() const { return "Servo"; }
128
129void Servo::InitTable(std::shared_ptr<ITable> subTable) {
130 m_table = subTable;
131 UpdateTable();
132}
133
134std::shared_ptr<ITable> Servo::GetTable() const { return m_table; }