jump_rope_count_device.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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->wait_time = cfg->wait_time;
  52. dev->cy_suppress = 0;
  53. return 0;
  54. }
  55. static float hypot3f(float x, float y, float z)
  56. {
  57. return sqrtf(x*x + y*y + z*z);
  58. }
  59. int process_packet(struct jump_rope_count_device *dev,
  60. struct sensor_packet *packet,
  61. enum jump_rope_count_result *result)
  62. {
  63. int ret = 0;
  64. float min, max;
  65. float g = hypot3f(packet->gx, packet->gy, packet->gz);
  66. float a = hypot3f(packet->ax, packet->ay, packet->az);
  67. float gz = packet->gz;
  68. ringbuf_push(&dev->rbuf_g, g);
  69. ringbuf_push(&dev->rbuf_a, a);
  70. schmidt_trig(&dev->trig_g, ringbuf_stdev(&dev->rbuf_g));
  71. schmidt_trig(&dev->trig_a, ringbuf_stdev(&dev->rbuf_a));
  72. ret = monotonic_queue_push(&dev->mq_min_cy, packet->cy);
  73. if (ret != 0)
  74. return ret;
  75. if (monotonic_queue_get_len(&dev->mq_min_cy) > dev->cy_window)
  76. ret = monotonic_queue_pop(&dev->mq_min_cy);
  77. if (ret != 0)
  78. return ret;
  79. ret = monotonic_queue_push(&dev->mq_max_cy, packet->cy);
  80. if (ret != 0)
  81. return ret;
  82. if (monotonic_queue_get_len(&dev->mq_max_cy) > dev->cy_window)
  83. ret = monotonic_queue_pop(&dev->mq_max_cy);
  84. if (ret != 0)
  85. return ret;
  86. ret = monotonic_queue_get_min(&dev->mq_min_cy, &min);
  87. if (ret != 0)
  88. return ret;
  89. ret = monotonic_queue_get_min(&dev->mq_max_cy, &max);
  90. if (ret != 0)
  91. return ret;
  92. if (max - min > dev->cy_crit)
  93. dev->cy_suppress = dev->cy_suppress_time;
  94. if (schmidt_get(&dev->trig_g) == 0 ||
  95. schmidt_get(&dev->trig_a) == 0 ||
  96. dev->cy_suppress > 0)
  97. {
  98. schmidt_trig(&dev->trig_gz, -INFINITY);
  99. *result = RESULT_INACTIVE;
  100. goto out;
  101. }
  102. if (schmidt_trig(&dev->trig_gz, gz) == 1 &&
  103. schmidt_get(&dev->trig_gz) == 0 &&
  104. dev->cy_suppress == 0)
  105. {
  106. dev->remain_time = dev->wait_time;
  107. *result = RESULT_TRIGGERED;
  108. goto out;
  109. }
  110. if (dev->remain_time)
  111. dev->remain_time--;
  112. *result = (dev->remain_time > 0 ? RESULT_NONE : RESULT_INACTIVE);
  113. out:
  114. if (dev->cy_suppress > 0)
  115. dev->cy_suppress--;
  116. return 0;
  117. }
  118. /* vim: set ts=8 sw=8 sts=8 noet: */