autocore_std/ethercat/
axis_config.rs1#[derive(Debug, Clone, Copy)]
28pub struct AxisConfig {
29 counts_per_rev: f64,
30 user_per_rev: f64,
32}
33
34impl AxisConfig {
35 pub const fn new(counts_per_rev: u32) -> Self {
38 Self {
39 counts_per_rev: counts_per_rev as f64,
40 user_per_rev: 1.0,
41 }
42 }
43
44 pub const fn with_user_scale(mut self, user_per_rev: f64) -> Self {
49 self.user_per_rev = user_per_rev;
50 self
51 }
52
53 pub fn rev(&self, revolutions: f64) -> i32 {
57 (revolutions * self.counts_per_rev).round() as i32
58 }
59
60 pub fn rps(&self, rev_per_sec: f64) -> u32 {
62 (rev_per_sec * self.counts_per_rev).round() as u32
63 }
64
65 pub fn rps2(&self, rev_per_sec2: f64) -> u32 {
67 (rev_per_sec2 * self.counts_per_rev).round() as u32
68 }
69
70 pub fn user(&self, units: f64) -> i32 {
74 (units / self.user_per_rev * self.counts_per_rev).round() as i32
75 }
76
77 pub fn user_per_s(&self, units_per_sec: f64) -> u32 {
79 (units_per_sec / self.user_per_rev * self.counts_per_rev).round() as u32
80 }
81
82 pub fn user_per_s2(&self, units_per_sec2: f64) -> u32 {
84 (units_per_sec2 / self.user_per_rev * self.counts_per_rev).round() as u32
85 }
86
87 pub fn to_rev(&self, counts: i32) -> f64 {
91 counts as f64 / self.counts_per_rev
92 }
93
94 pub fn to_rps(&self, counts_per_sec: u32) -> f64 {
96 counts_per_sec as f64 / self.counts_per_rev
97 }
98
99 pub fn to_user(&self, counts: i32) -> f64 {
103 counts as f64 / self.counts_per_rev * self.user_per_rev
104 }
105
106 pub fn to_user_per_s(&self, counts_per_sec: u32) -> f64 {
108 counts_per_sec as f64 / self.counts_per_rev * self.user_per_rev
109 }
110}
111
112#[cfg(test)]
113mod tests {
114 use super::*;
115
116 const CPR: u32 = 12_800;
117
118 #[test]
119 fn rev_position() {
120 let cfg = AxisConfig::new(CPR);
121 assert_eq!(cfg.rev(0.125), 1_600);
122 assert_eq!(cfg.rev(1.0), 12_800);
123 assert_eq!(cfg.rev(-0.5), -6_400);
124 }
125
126 #[test]
127 fn rev_velocity_accel() {
128 let cfg = AxisConfig::new(CPR);
129 assert_eq!(cfg.rps(1.0), 12_800);
130 assert_eq!(cfg.rps2(1.0), 12_800);
131 }
132
133 #[test]
134 fn user_degrees() {
135 let deg = AxisConfig::new(CPR).with_user_scale(360.0);
136 assert_eq!(deg.user(45.0), 1_600);
137 assert_eq!(deg.user(360.0), 12_800);
138 assert_eq!(deg.user(90.0), 3_200);
139 }
140
141 #[test]
142 fn user_mm_ballscrew() {
143 let mm = AxisConfig::new(CPR).with_user_scale(5.0);
144 assert_eq!(mm.user(5.0), 12_800);
145 assert_eq!(mm.user(2.5), 6_400);
146 }
147
148 #[test]
149 fn user_velocity_accel() {
150 let deg = AxisConfig::new(CPR).with_user_scale(360.0);
151 assert_eq!(deg.user_per_s(90.0), 3_200);
153 assert_eq!(deg.user_per_s2(180.0), 6_400);
155 }
156
157 #[test]
158 fn round_trip_rev() {
159 let cfg = AxisConfig::new(CPR);
160 let original = 0.125;
161 let counts = cfg.rev(original);
162 let back = cfg.to_rev(counts);
163 assert!((back - original).abs() < 1e-9);
164 }
165
166 #[test]
167 fn round_trip_user() {
168 let deg = AxisConfig::new(CPR).with_user_scale(360.0);
169 let original = 45.0;
170 let counts = deg.user(original);
171 let back = deg.to_user(counts);
172 assert!((back - original).abs() < 0.1);
173 }
174
175 #[test]
176 fn round_trip_velocity() {
177 let cfg = AxisConfig::new(CPR);
178 let original = 7.8125;
179 let counts = cfg.rps(original);
180 let back = cfg.to_rps(counts);
181 assert!((back - original).abs() < 1e-9);
182 }
183
184 #[test]
185 fn to_user_per_s() {
186 let deg = AxisConfig::new(CPR).with_user_scale(360.0);
187 assert!((deg.to_user_per_s(3_200) - 90.0).abs() < 1e-9);
189 }
190
191 #[test]
192 fn const_construction() {
193 const CFG: AxisConfig = AxisConfig::new(12_800).with_user_scale(360.0);
195 assert_eq!(CFG.user(45.0), 1_600);
196 }
197}