-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEncoderMapper.java
More file actions
109 lines (93 loc) · 3.86 KB
/
EncoderMapper.java
File metadata and controls
109 lines (93 loc) · 3.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package org.xerosw.util;
/// \file
/// \brief This class maps encoder counts to real world physical quantities
/// It also maps real world physical quantities to encoder counts. It does this over a range
/// the the encoders may be increasing or decreasing in the same or opposite direction
/// than the physical value. Also, the zero point for the encoder may be at any point along
/// the travel of the physical quantity. See the examples below where the encoder zero point is in
/// the middle of the physical range and the encoder value "wraps" as you traverse through the physical
/// range of the device.
/// <pre>
/// Physical
/// 0 10 20 30 40 50 60 70 80 90 100
/// +---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
///
/// +---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
/// 3.0 3.5 4.0 4.5 5.0/0.0 0.5 1.0 1.5 2.0 2.5 3.0
/// Encoders
/// </pre>
public class EncoderMapper {
private double kEncoder2Robot_;
private double rmax_;
private double rmin_;
private double rc_;
private double emax_;
private double emin_;
private double ec_;
/// \brief create a new encoder mapper objects
/// \param rmax the maximum range of the robot physical characteristic
/// \param rmin the minimum range of the robot physical characteristic
/// \param emax the maximum range of the electrical value returned from the
/// encoder
/// \param emin the minimum range of the electrical value returned from the
/// encoder
public EncoderMapper(double rmax, double rmin, double emax, double emin) {
rmax_ = rmax;
rmin_ = rmin;
emax_ = emax;
emin_ = emin;
kEncoder2Robot_ = (rmax - rmin) / (emax - emin);
}
/// \brief calibrate the encoder mapper.
/// This establishes the wrap point of the encoder versus the physical system
/// being measured.
/// \param robot a reading from the robot
/// \param encoder a reading from the encoder
public void calibrate(double robot, double encoder) {
ec_ = encoder;
rc_ = robot;
}
/// \brief convert an encoder value to a physical robot value
/// \param encoder the encoder value
/// \returns the robot value
public double toRobot(double encoder) {
double ret;
double offset;
encoder = clamp(encoder, emax_, emin_);
offset = normalize(ec_ - (rc_ - rmin_) / kEncoder2Robot_, emax_, emin_);
ret = normalize((encoder - offset) * kEncoder2Robot_ + rmin_, rmax_, rmin_);
return ret;
}
/// \brief convert an robot value to a encoder value
/// \param robot the robot value
/// \returns the encoder value
public double toEncoder(double robot) {
double ret;
double offset;
robot = clamp(robot, rmax_, rmin_);
offset = normalize(ec_ - (rc_ - rmin_) / kEncoder2Robot_, emax_, emin_);
ret = normalize(offset + (robot - rmin_) / kEncoder2Robot_, emax_, emin_);
return ret;
}
private double normalize(double value, double vmax, double vmin) {
if (vmax < vmin) {
double temp = vmax;
vmax = vmin;
vmin = temp;
}
value = value + (vmax - vmin) * -Math.floor(((value - vmin) / (vmax - vmin)));
return value;
}
private double clamp(double value, double vmax, double vmin) {
if (vmax < vmin) {
double temp = vmax;
vmax = vmin;
vmin = temp;
}
if (value > vmax)
value = vmax;
else if (value < vmin)
value = vmin;
return value;
}
}