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