blob: b1b4d0744f09ad12c4ae60f9db49a1782b8639a7 [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#pragma once
9
10#include <memory>
11#include <string>
12
13#include "LiveWindow/LiveWindowSendable.h"
14#include "SensorBase.h"
15#include "simulation/SimContinuousOutput.h"
16#include "tables/ITableListener.h"
17
18namespace frc {
19
20/**
21 * Class implements the PWM generation in the FPGA.
22 *
23 * The values supplied as arguments for PWM outputs range from -1.0 to 1.0. They
24 * are mapped to the hardware dependent values, in this case 0-255 for the FPGA.
25 * Changes are immediately sent to the FPGA, and the update occurs at the next
26 * FPGA cycle. There is no delay.
27 *
28 * As of revision 0.1.10 of the FPGA, the FPGA interprets the 0-255 values as
29 * follows:
30 * - 255 = full "forward"
31 * - 254 to 129 = linear scaling from "full forward" to "center"
32 * - 128 = center value
33 * - 127 to 2 = linear scaling from "center" to "full reverse"
34 * - 1 = full "reverse"
35 * - 0 = disabled (i.e. PWM output is held low)
36 */
37class PWM : public SensorBase,
38 public ITableListener,
39 public LiveWindowSendable {
40 public:
41 enum PeriodMultiplier {
42 kPeriodMultiplier_1X = 1,
43 kPeriodMultiplier_2X = 2,
44 kPeriodMultiplier_4X = 4
45 };
46
47 explicit PWM(int channel);
48 virtual ~PWM();
49 virtual void SetRaw(uint16_t value);
50 void SetPeriodMultiplier(PeriodMultiplier mult);
51 void EnableDeadbandElimination(bool eliminateDeadband);
52 void SetBounds(int max, int deadbandMax, int center, int deadbandMin,
53 int min);
54 void SetBounds(double max, double deadbandMax, double center,
55 double deadbandMin, double min);
56 int GetChannel() const { return m_channel; }
57
58 protected:
59 /**
60 * kDefaultPwmPeriod is in ms
61 *
62 * - 20ms periods (50 Hz) are the "safest" setting in that this works for all
63 * devices
64 * - 20ms periods seem to be desirable for Vex Motors
65 * - 20ms periods are the specified period for HS-322HD servos, but work
66 * reliably down to 10.0 ms; starting at about 8.5ms, the servo sometimes
67 * hums and get hot; by 5.0ms the hum is nearly continuous
68 * - 10ms periods work well for Victor 884
69 * - 5ms periods allows higher update rates for Luminary Micro Jaguar speed
70 * controllers. Due to the shipping firmware on the Jaguar, we can't run
71 * the update period less than 5.05 ms.
72 *
73 * kDefaultPwmPeriod is the 1x period (5.05 ms). In hardware, the period
74 * scaling is implemented as an output squelch to get longer periods for old
75 * devices.
76 */
77 static const double kDefaultPwmPeriod;
78 /**
79 * kDefaultPwmCenter is the PWM range center in ms
80 */
81 static const double kDefaultPwmCenter;
82 /**
83 * kDefaultPWMStepsDown is the number of PWM steps below the centerpoint
84 */
85 static const int kDefaultPwmStepsDown;
86 static const int kPwmDisabled;
87
88 virtual void SetPosition(double pos);
89 virtual double GetPosition() const;
90 virtual void SetSpeed(double speed);
91 virtual double GetSpeed() const;
92
93 bool m_eliminateDeadband;
94 int m_centerPwm;
95
96 void ValueChanged(ITable* source, llvm::StringRef key,
97 std::shared_ptr<nt::Value> value, bool isNew) override;
98 void UpdateTable() override;
99 void StartLiveWindowMode() override;
100 void StopLiveWindowMode() override;
101 std::string GetSmartDashboardType() const override;
102 void InitTable(std::shared_ptr<ITable> subTable) override;
103 std::shared_ptr<ITable> GetTable() const override;
104
105 std::shared_ptr<ITable> m_table;
106
107 private:
108 int m_channel;
109 SimContinuousOutput* impl;
110};
111
112} // namespace frc