@@ -5,10 +5,7 @@ import (
5
5
"sync"
6
6
"sync/atomic"
7
7
8
- "github.com/erh/scheme"
9
8
"github.com/pkg/errors"
10
-
11
- "go.viam.com/rdk/utils"
12
9
)
13
10
14
11
// ServoRollingAverageWindow is how many entries to average over for
@@ -27,8 +24,7 @@ type Tick struct {
27
24
}
28
25
29
26
// A DigitalInterrupt represents a configured interrupt on the board that
30
- // when interrupted, calls the added callbacks. Post processors can also
31
- // be added to modify what Value ultimately returns.
27
+ // when interrupted, calls the added callbacks.
32
28
type DigitalInterrupt interface {
33
29
// Value returns the current value of the interrupt which is
34
30
// based on the type of interrupt.
@@ -44,10 +40,6 @@ type DigitalInterrupt interface {
44
40
// happens.
45
41
AddCallback (c chan Tick )
46
42
47
- // AddPostProcessor adds a post processor that should be used to modify
48
- // what is returned by Value.
49
- AddPostProcessor (pp PostProcessor )
50
-
51
43
// RemoveCallback removes a listener for interrupts
52
44
RemoveCallback (c chan Tick )
53
45
@@ -64,19 +56,7 @@ type ReconfigurableDigitalInterrupt interface {
64
56
// CreateDigitalInterrupt is a factory method for creating a specific DigitalInterrupt based
65
57
// on the given config. If no type is specified, a BasicDigitalInterrupt is returned.
66
58
func CreateDigitalInterrupt (cfg DigitalInterruptConfig ) (ReconfigurableDigitalInterrupt , error ) {
67
- if cfg .Type == "" {
68
- cfg .Type = "basic"
69
- }
70
-
71
- var i ReconfigurableDigitalInterrupt
72
- switch cfg .Type {
73
- case "basic" :
74
- i = & BasicDigitalInterrupt {}
75
- case "servo" :
76
- i = & ServoDigitalInterrupt {ra : utils .NewRollingAverage (ServoRollingAverageWindow )}
77
- default :
78
- panic (errors .Errorf ("unknown interrupt type (%s)" , cfg .Type ))
79
- }
59
+ i := & BasicDigitalInterrupt {}
80
60
81
61
if err := i .Reconfigure (cfg ); err != nil {
82
62
return nil , err
@@ -93,24 +73,13 @@ type BasicDigitalInterrupt struct {
93
73
94
74
mu sync.RWMutex
95
75
cfg DigitalInterruptConfig
96
- pp PostProcessor
97
- }
98
-
99
- // Config returns the config used to create this interrupt.
100
- func (i * BasicDigitalInterrupt ) Config (ctx context.Context ) (DigitalInterruptConfig , error ) {
101
- i .mu .RLock ()
102
- defer i .mu .RUnlock ()
103
- return i .cfg , nil
104
76
}
105
77
106
78
// Value returns the amount of ticks that have occurred.
107
79
func (i * BasicDigitalInterrupt ) Value (ctx context.Context , extra map [string ]interface {}) (int64 , error ) {
108
80
i .mu .RLock ()
109
81
defer i .mu .RUnlock ()
110
82
count := atomic .LoadInt64 (& i .count )
111
- if i .pp != nil {
112
- return i .pp (count ), nil
113
- }
114
83
return count , nil
115
84
}
116
85
@@ -165,162 +134,16 @@ func (i *BasicDigitalInterrupt) RemoveCallback(c chan Tick) {
165
134
}
166
135
}
167
136
168
- // AddPostProcessor sets the post processor that will modify the value that
169
- // Value returns.
170
- func (i * BasicDigitalInterrupt ) AddPostProcessor (pp PostProcessor ) {
171
- i .mu .Lock ()
172
- defer i .mu .Unlock ()
173
- i .pp = pp
174
- }
175
-
176
137
// Close does nothing.
177
138
func (i * BasicDigitalInterrupt ) Close (ctx context.Context ) error {
178
139
return nil
179
140
}
180
141
181
- func processFormula (oldFormula , newFormula , name string ) (func (raw int64 ) int64 , bool , error ) {
182
- if oldFormula == newFormula {
183
- return nil , false , nil
184
- }
185
- x , err := scheme .Parse (newFormula )
186
- if err != nil {
187
- return nil , false , errors .Wrapf (err , "couldn't parse formula for %s" , name )
188
- }
189
-
190
- testScope := scheme.Scope {}
191
- num := 1.0
192
- testScope ["raw" ] = & scheme.Value {Float : & num }
193
- _ , err = scheme .Eval (x , testScope )
194
- if err != nil {
195
- return nil , false , errors .Wrapf (err , "test exec failed for %s" , name )
196
- }
197
-
198
- return func (raw int64 ) int64 {
199
- scope := scheme.Scope {}
200
- rr := float64 (raw ) // TODO(erh): fix
201
- scope ["raw" ] = & scheme.Value {Float : & rr }
202
- res , err := scheme .Eval (x , scope )
203
- if err != nil {
204
- panic (err )
205
- }
206
- f , err := res .ToFloat ()
207
- if err != nil {
208
- panic (err )
209
- }
210
- return int64 (f )
211
- }, true , nil
212
- }
213
-
214
142
// Reconfigure reconfigures this digital interrupt with a new formula.
215
143
func (i * BasicDigitalInterrupt ) Reconfigure (conf DigitalInterruptConfig ) error {
216
144
i .mu .Lock ()
217
145
defer i .mu .Unlock ()
218
146
219
- newFormula , isNew , err := processFormula (i .cfg .Formula , conf .Formula , conf .Name )
220
- if err != nil {
221
- return err
222
- }
223
- if ! isNew {
224
- return nil
225
- }
226
- i .pp = newFormula
227
147
i .cfg = conf
228
148
return nil
229
149
}
230
-
231
- // A ServoDigitalInterrupt is an interrupt associated with a servo in order to
232
- // track the amount of time that has passed between low signals (pulse width). Post processors
233
- // make meaning of these widths.
234
- type ServoDigitalInterrupt struct {
235
- last uint64
236
- ra * utils.RollingAverage
237
-
238
- mu sync.RWMutex
239
- cfg DigitalInterruptConfig
240
- pp PostProcessor
241
- }
242
-
243
- // Config returns the config the interrupt was created with.
244
- func (i * ServoDigitalInterrupt ) Config (ctx context.Context ) (DigitalInterruptConfig , error ) {
245
- i .mu .RLock ()
246
- defer i .mu .RUnlock ()
247
- return i .cfg , nil
248
- }
249
-
250
- // Value will return the window averaged value followed by its post processed
251
- // result.
252
- func (i * ServoDigitalInterrupt ) Value (ctx context.Context , extra map [string ]interface {}) (int64 , error ) {
253
- i .mu .RLock ()
254
- defer i .mu .RUnlock ()
255
- v := int64 (i .ra .Average ())
256
- if i .pp != nil {
257
- return i .pp (v ), nil
258
- }
259
-
260
- return v , nil
261
- }
262
-
263
- // Tick records the time between two successive low signals (pulse width). How it is
264
- // interpreted is based off the consumer of Value.
265
- func (i * ServoDigitalInterrupt ) Tick (ctx context.Context , high bool , now uint64 ) error {
266
- i .mu .RLock ()
267
- defer i .mu .RUnlock ()
268
- diff := now - i .last
269
- i .last = now
270
-
271
- if i .last == 0 {
272
- return nil
273
- }
274
-
275
- if high {
276
- // this is time between signals, ignore
277
- return nil
278
- }
279
-
280
- i .ra .Add (int (diff / 1000 ))
281
- return nil
282
- }
283
-
284
- // AddCallback currently panics.
285
- func (i * ServoDigitalInterrupt ) AddCallback (c chan Tick ) {
286
- i .mu .Lock ()
287
- defer i .mu .Unlock ()
288
- panic ("servos can't have callback" )
289
- }
290
-
291
- // RemoveCallback currently panics.
292
- func (i * ServoDigitalInterrupt ) RemoveCallback (c chan Tick ) {
293
- i .mu .Lock ()
294
- defer i .mu .Unlock ()
295
- panic ("servos can't have callback" )
296
- }
297
-
298
- // AddPostProcessor sets the post processor that will modify the value that
299
- // Value returns.
300
- func (i * ServoDigitalInterrupt ) AddPostProcessor (pp PostProcessor ) {
301
- i .mu .Lock ()
302
- defer i .mu .Unlock ()
303
- i .pp = pp
304
- }
305
-
306
- // Reconfigure reconfigures this digital interrupt with a new formula.
307
- func (i * ServoDigitalInterrupt ) Reconfigure (conf DigitalInterruptConfig ) error {
308
- i .mu .Lock ()
309
- defer i .mu .Unlock ()
310
-
311
- newFormula , isNew , err := processFormula (i .cfg .Formula , conf .Formula , conf .Name )
312
- if err != nil {
313
- return err
314
- }
315
- if ! isNew {
316
- return nil
317
- }
318
- i .pp = newFormula
319
- i .cfg = conf
320
- return nil
321
- }
322
-
323
- // Close does nothing.
324
- func (i * ServoDigitalInterrupt ) Close (ctx context.Context ) error {
325
- return nil
326
- }
0 commit comments