jerrym | f157933 | 2013-02-07 01:56:28 +0000 | [diff] [blame] | 1 | /*----------------------------------------------------------------------------*/
|
| 2 | /* Copyright (c) FIRST 2008. 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 $(WIND_BASE)/WPILib. */
|
| 5 | /*----------------------------------------------------------------------------*/
|
| 6 |
|
| 7 | #include "Servo.h"
|
| 8 |
|
| 9 | #include "NetworkCommunication/UsageReporting.h"
|
| 10 | #include "LiveWindow/LiveWindow.h"
|
| 11 |
|
| 12 | const float Servo::kMaxServoAngle;
|
| 13 | const float Servo::kMinServoAngle;
|
| 14 |
|
| 15 | /**
|
| 16 | * Common initialization code called by all constructors.
|
| 17 | *
|
| 18 | * InitServo() assigns defaults for the period multiplier for the servo PWM control signal, as
|
| 19 | * well as the minimum and maximum PWM values supported by the servo.
|
| 20 | */
|
| 21 | void Servo::InitServo()
|
| 22 | {
|
jerrym | 37afdca | 2013-03-03 01:17:57 +0000 | [diff] [blame] | 23 | m_table = NULL;
|
jerrym | f157933 | 2013-02-07 01:56:28 +0000 | [diff] [blame] | 24 | // TODO: compute the appropriate values based on digital loop timing
|
| 25 | SetBounds(245, 0, 0, 0, 11);
|
| 26 | SetPeriodMultiplier(kPeriodMultiplier_4X);
|
| 27 |
|
| 28 |
|
| 29 | LiveWindow::GetInstance()->AddActuator("Servo", GetModuleNumber(), GetChannel(), this);
|
| 30 | nUsageReporting::report(nUsageReporting::kResourceType_Servo, GetChannel(), GetModuleNumber() - 1);
|
| 31 | }
|
| 32 |
|
| 33 | /**
|
| 34 | * Constructor that assumes the default digital module.
|
| 35 | *
|
| 36 | * @param channel The PWM channel on the digital module to which the servo is attached.
|
| 37 | */
|
| 38 | Servo::Servo(UINT32 channel) : SafePWM(channel)
|
| 39 | {
|
| 40 | InitServo();
|
| 41 | }
|
| 42 |
|
| 43 | /**
|
| 44 | * Constructor that specifies the digital module.
|
| 45 | *
|
| 46 | * @param moduleNumber The digital module (1 or 2).
|
| 47 | * @param channel The PWM channel on the digital module to which the servo is attached (1..10).
|
| 48 | */
|
| 49 | Servo::Servo(UINT8 moduleNumber, UINT32 channel) : SafePWM(moduleNumber, channel)
|
| 50 | {
|
| 51 | InitServo();
|
| 52 | }
|
| 53 |
|
| 54 | Servo::~Servo()
|
| 55 | {
|
| 56 | }
|
| 57 |
|
| 58 | /**
|
| 59 | * Set the servo position.
|
| 60 | *
|
| 61 | * Servo values range from 0.0 to 1.0 corresponding to the range of full left to full right.
|
| 62 | *
|
| 63 | * @param value Position from 0.0 to 1.0.
|
| 64 | */
|
| 65 | void Servo::Set(float value)
|
| 66 | {
|
| 67 | SetPosition(value);
|
| 68 | }
|
| 69 |
|
| 70 | /**
|
| 71 | * Set the servo to offline.
|
| 72 | *
|
| 73 | * Set the servo raw value to 0 (undriven)
|
| 74 | */
|
| 75 | void Servo::SetOffline() {
|
| 76 | SetRaw(0);
|
| 77 | }
|
| 78 |
|
| 79 | /**
|
| 80 | * Get the servo position.
|
| 81 | *
|
| 82 | * Servo values range from 0.0 to 1.0 corresponding to the range of full left to full right.
|
| 83 | *
|
| 84 | * @return Position from 0.0 to 1.0.
|
| 85 | */
|
| 86 | float Servo::Get()
|
| 87 | {
|
| 88 | return GetPosition();
|
| 89 | }
|
| 90 |
|
| 91 | /**
|
| 92 | * Set the servo angle.
|
| 93 | *
|
| 94 | * Assume that the servo angle is linear with respect to the PWM value (big assumption, need to test).
|
| 95 | *
|
| 96 | * Servo angles that are out of the supported range of the servo simply "saturate" in that direction
|
| 97 | * In other words, if the servo has a range of (X degrees to Y degrees) than angles of less than X
|
| 98 | * result in an angle of X being set and angles of more than Y degrees result in an angle of Y being set.
|
| 99 | *
|
| 100 | * @param degrees The angle in degrees to set the servo.
|
| 101 | */
|
| 102 | void Servo::SetAngle(float degrees)
|
| 103 | {
|
| 104 | if (degrees < kMinServoAngle)
|
| 105 | {
|
| 106 | degrees = kMinServoAngle;
|
| 107 | }
|
| 108 | else if (degrees > kMaxServoAngle)
|
| 109 | {
|
| 110 | degrees = kMaxServoAngle;
|
| 111 | }
|
| 112 |
|
| 113 | SetPosition(((float) (degrees - kMinServoAngle)) / GetServoAngleRange());
|
| 114 | }
|
| 115 |
|
| 116 | /**
|
| 117 | * Get the servo angle.
|
| 118 | *
|
| 119 | * Assume that the servo angle is linear with respect to the PWM value (big assumption, need to test).
|
| 120 | * @return The angle in degrees to which the servo is set.
|
| 121 | */
|
| 122 | float Servo::GetAngle()
|
| 123 | {
|
| 124 | return (float)GetPosition() * GetServoAngleRange() + kMinServoAngle;
|
| 125 | }
|
| 126 |
|
| 127 | void Servo::ValueChanged(ITable* source, const std::string& key, EntryValue value, bool isNew) {
|
| 128 | Set(value.f);
|
| 129 | }
|
| 130 |
|
| 131 | void Servo::UpdateTable() {
|
| 132 | if (m_table != NULL) {
|
| 133 | m_table->PutNumber("Value", Get());
|
| 134 | }
|
| 135 | }
|
| 136 |
|
| 137 | void Servo::StartLiveWindowMode() {
|
jerrym | 37afdca | 2013-03-03 01:17:57 +0000 | [diff] [blame] | 138 | if (m_table != NULL) {
|
| 139 | m_table->AddTableListener("Value", this, true);
|
| 140 | }
|
jerrym | f157933 | 2013-02-07 01:56:28 +0000 | [diff] [blame] | 141 | }
|
| 142 |
|
| 143 | void Servo::StopLiveWindowMode() {
|
jerrym | 37afdca | 2013-03-03 01:17:57 +0000 | [diff] [blame] | 144 | if (m_table != NULL) {
|
| 145 | m_table->RemoveTableListener(this);
|
| 146 | }
|
jerrym | f157933 | 2013-02-07 01:56:28 +0000 | [diff] [blame] | 147 | }
|
| 148 |
|
| 149 | std::string Servo::GetSmartDashboardType() {
|
| 150 | return "Servo";
|
| 151 | }
|
| 152 |
|
| 153 | void Servo::InitTable(ITable *subTable) {
|
| 154 | m_table = subTable;
|
| 155 | UpdateTable();
|
| 156 | }
|
| 157 |
|
| 158 | ITable * Servo::GetTable() {
|
| 159 | return m_table;
|
| 160 | }
|
| 161 |
|
| 162 |
|