A PX4 based camera pointer

filter.go 1.9KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Copyright 2017 Google Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. package pipoint
  16. // Lowpass is a first order low pass filter.
  17. type Lowpass struct {
  18. // The current filter output.
  19. Acc float64
  20. }
  21. // StepEx feeds v into the filter and returns the filtered value. Tau
  22. // is the filter coefficient, where 1.0 is no filtering and 0.0 is no
  23. // pass through.
  24. func (l *Lowpass) StepEx(v, tau float64) float64 {
  25. l.Acc = tau*v + (1-tau)*l.Acc
  26. return l.Acc
  27. }
  28. // LinPred is a velocity based linear predictive filter.
  29. type LinPred struct {
  30. x float64
  31. stamp float64
  32. updated float64
  33. v float64
  34. }
  35. // SetEx is called when a new measurement arrives. x is the
  36. // measurement, now is the local time this function was called, and
  37. // stamp is the sensor specific time the measurement was made.
  38. //
  39. // The velocity is calculated based on sensor time. The prediction is
  40. // based on local time.
  41. func (l *LinPred) SetEx(x, now, stamp float64) {
  42. if l.stamp == 0 {
  43. // First run
  44. l.v = 0
  45. } else {
  46. dt := stamp - l.stamp
  47. dx := x - l.x
  48. if dt <= 0 {
  49. l.v = 0
  50. } else {
  51. l.v = dx / dt
  52. }
  53. }
  54. l.x = x
  55. l.stamp = stamp
  56. l.updated = now
  57. }
  58. // GetEx returns the predicted measurement based on the given local
  59. // time.
  60. func (l *LinPred) GetEx(now float64) float64 {
  61. dt := now - l.updated
  62. if dt < 0 {
  63. dt = 0
  64. } else if dt > 2 {
  65. // Clamp if the value hasn't been updated recently.
  66. dt = 2
  67. }
  68. return l.x + l.v*dt
  69. }