jump_rope_count_device.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #include <math.h>
  2. #include "jump_rope_count_device.h"
  3. #include "schmidt_trigger.h"
  4. #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
  5. /* Before C99, sqrtf is not avaliable. */
  6. float _sqrtf(float x)
  7. {
  8. return (float)sqrt(x);
  9. }
  10. #define sqrtf _sqrtf
  11. /* Before C99, INFINITY is not avaliable. */
  12. #if defined __GNUC__ && (__GNUC__ > 3 || \
  13. (__GNUC__ == 3 && __GNUC_MINOR >= 3))
  14. #define INFINITY (__builtin_inff())
  15. #else
  16. #define INFINITY 1e10000f
  17. #endif
  18. #endif
  19. static int less(float a, float b)
  20. {
  21. return a < b;
  22. }
  23. static int greater(float a, float b)
  24. {
  25. return a > b;
  26. }
  27. int jump_rope_count_device_init(struct jump_rope_count_device *dev,
  28. struct jump_rope_count_config *cfg)
  29. {
  30. int ret;
  31. ret = schmidt_init(&dev->trig_g, cfg->lg, cfg->hg);
  32. if (ret != 0)
  33. return ret;
  34. ret = schmidt_init(&dev->trig_a, cfg->la, cfg->ha);
  35. if (ret != 0)
  36. return ret;
  37. ret = schmidt_init(&dev->trig_gz, cfg->lgz, cfg->hgz);
  38. if (ret != 0)
  39. return ret;
  40. ret = ringbuf_init(&dev->rbuf_a, cfg->a_g_window);
  41. if (ret != 0)
  42. return ret;
  43. ret = ringbuf_init(&dev->rbuf_g, cfg->a_g_window);
  44. if (ret != 0)
  45. return ret;
  46. monotonic_queue_init(&dev->mq_min_cy, less);
  47. monotonic_queue_init(&dev->mq_max_cy, greater);
  48. dev->cy_window = cfg->cy_window;
  49. dev->cy_crit = cfg->cy_crit;
  50. dev->cy_suppress_time = cfg->cy_suppress_time;
  51. dev->cy_suppress = 0;
  52. return 0;
  53. }
  54. static float hypot3f(float x, float y, float z)
  55. {
  56. return sqrtf(x*x + y*y + z*z);
  57. }
  58. int process_packet(struct jump_rope_count_device *dev,
  59. struct sensor_packet *packet,
  60. enum jump_rope_count_result *result)
  61. {
  62. int ret = 0;
  63. float min, max;
  64. float g = hypot3f(packet->gx, packet->gy, packet->gz);
  65. float a = hypot3f(packet->ax, packet->ay, packet->az);
  66. float gz = packet->gz;
  67. ringbuf_push(&dev->rbuf_g, g);
  68. ringbuf_push(&dev->rbuf_a, a);
  69. schmidt_trig(&dev->trig_g, ringbuf_stdev(&dev->rbuf_g));
  70. schmidt_trig(&dev->trig_a, ringbuf_stdev(&dev->rbuf_a));
  71. ret = monotonic_queue_push(&dev->mq_min_cy, packet->cy);
  72. if (ret != 0)
  73. return ret;
  74. if (monotonic_queue_get_len(&dev->mq_min_cy) > dev->cy_window)
  75. ret = monotonic_queue_pop(&dev->mq_min_cy);
  76. if (ret != 0)
  77. return ret;
  78. ret = monotonic_queue_push(&dev->mq_max_cy, packet->cy);
  79. if (ret != 0)
  80. return ret;
  81. if (monotonic_queue_get_len(&dev->mq_max_cy) > dev->cy_window)
  82. ret = monotonic_queue_pop(&dev->mq_max_cy);
  83. if (ret != 0)
  84. return ret;
  85. ret = monotonic_queue_get_min(&dev->mq_min_cy, &min);
  86. if (ret != 0)
  87. return ret;
  88. ret = monotonic_queue_get_min(&dev->mq_max_cy, &max);
  89. if (ret != 0)
  90. return ret;
  91. if (max - min > dev->cy_crit)
  92. dev->cy_suppress = dev->cy_suppress_time;
  93. if (schmidt_get(&dev->trig_g) == 0 ||
  94. schmidt_get(&dev->trig_a) == 0 ||
  95. dev->cy_suppress > 0)
  96. {
  97. schmidt_trig(&dev->trig_gz, -INFINITY);
  98. *result = RESULT_INACTIVE;
  99. goto out;
  100. }
  101. if (schmidt_trig(&dev->trig_gz, gz) == 1 &&
  102. schmidt_get(&dev->trig_gz) == 1 &&
  103. dev->cy_suppress == 0)
  104. {
  105. *result = RESULT_TRIGGERED;
  106. goto out;
  107. }
  108. *result = RESULT_NONE;
  109. out:
  110. if (dev->cy_suppress > 0)
  111. dev->cy_suppress--;
  112. return 0;
  113. }
  114. /* vim: set ts=8 sw=8 sts=8 noet: */