PX4 Firmware
PX4 Autopilot Software http://px4.io
sf0x.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2014-2015 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 /**
35  * @file sf0x.cpp
36  * @author Lorenz Meier <lm@inf.ethz.ch>
37  * @author Greg Hulands
38  *
39  * Driver for the Lightware SF0x laser rangefinder series
40  */
41 
42 #include <px4_platform_common/px4_config.h>
43 #include <px4_platform_common/getopt.h>
44 #include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>
45 
46 #include <sys/types.h>
47 #include <stdint.h>
48 #include <stdlib.h>
49 #include <stdbool.h>
50 #include <semaphore.h>
51 #include <string.h>
52 #include <fcntl.h>
53 #include <poll.h>
54 #include <errno.h>
55 #include <stdio.h>
56 #include <math.h>
57 #include <unistd.h>
58 #include <termios.h>
59 
60 #include <perf/perf_counter.h>
61 
62 #include <drivers/drv_hrt.h>
64 #include <drivers/device/device.h>
66 #include <lib/parameters/param.h>
67 
68 #include <uORB/uORB.h>
70 
71 #include "sf0x_parser.h"
72 
73 /* Configuration Constants */
74 
75 #define SF0X_TAKE_RANGE_REG 'd'
76 
77 // designated SERIAL4/5 on Pixhawk
78 #define SF0X_DEFAULT_PORT "/dev/ttyS6"
79 
80 class SF0X : public cdev::CDev, public px4::ScheduledWorkItem
81 {
82 public:
83  SF0X(const char *port = SF0X_DEFAULT_PORT, uint8_t rotation = distance_sensor_s::ROTATION_DOWNWARD_FACING);
84  virtual ~SF0X();
85 
86  virtual int init() override;
87 
88  virtual ssize_t read(device::file_t *filp, char *buffer, size_t buflen) override;
89  virtual int ioctl(device::file_t *filp, int cmd, unsigned long arg) override;
90 
91  /**
92  * Diagnostics - print some basic information about the driver.
93  */
94  void print_info();
95 
96 private:
97  char _port[20];
98  uint8_t _rotation;
102  ringbuffer::RingBuffer *_reports;
105  int _fd;
106  char _linebuf[10];
107  unsigned _linebuf_index;
110 
113 
115 
117 
120 
121  /**
122  * Initialise the automatic measurement state machine and start it.
123  *
124  * @note This function is called at open and error time. It might make sense
125  * to make it more aggressive about resetting the bus in case of errors.
126  */
127  void start();
128 
129  /**
130  * Stop the automatic measurement state machine.
131  */
132  void stop();
133 
134  /**
135  * Set the min and max distance thresholds if you want the end points of the sensors
136  * range to be brought in at all, otherwise it will use the defaults SF0X_MIN_DISTANCE
137  * and SF0X_MAX_DISTANCE
138  */
139  void set_minimum_distance(float min);
140  void set_maximum_distance(float max);
141  float get_minimum_distance();
142  float get_maximum_distance();
143 
144  /**
145  * Perform a poll cycle; collect from the previous measurement
146  * and start a new one.
147  */
148  void Run() override;
149  int measure();
150  int collect();
151 
152 };
153 
154 /*
155  * Driver 'main' command.
156  */
157 extern "C" __EXPORT int sf0x_main(int argc, char *argv[]);
158 
159 SF0X::SF0X(const char *port, uint8_t rotation) :
161  ScheduledWorkItem(MODULE_NAME, px4::serial_port_to_wq(port)),
162  _rotation(rotation),
163  _min_distance(0.30f),
164  _max_distance(40.0f),
165  _conversion_interval(83334),
166  _reports(nullptr),
168  _collect_phase(false),
169  _fd(-1),
170  _linebuf_index(0),
172  _last_read(0),
173  _class_instance(-1),
175  _distance_sensor_topic(nullptr),
177  _sample_perf(perf_alloc(PC_ELAPSED, "sf0x_read")),
178  _comms_errors(perf_alloc(PC_COUNT, "sf0x_com_err"))
179 {
180  /* store port name */
181  strncpy(_port, port, sizeof(_port) - 1);
182 
183  /* enforce null termination */
184  _port[sizeof(_port) - 1] = '\0';
185 
186 }
187 
189 {
190  /* make sure we are truly inactive */
191  stop();
192 
193  /* free any existing reports */
194  if (_reports != nullptr) {
195  delete _reports;
196  }
197 
198  if (_class_instance != -1) {
200  }
201 
204 }
205 
206 int
208 {
209  int hw_model;
210  param_get(param_find("SENS_EN_SF0X"), &hw_model);
211 
212  switch (hw_model) {
213 
214  case 1: /* SF02 (40m, 12 Hz)*/
215  _min_distance = 0.3f;
216  _max_distance = 40.0f;
217  _conversion_interval = 83334;
218  break;
219 
220  case 2: /* SF10/a (25m 32Hz) */
221  _min_distance = 0.01f;
222  _max_distance = 25.0f;
223  _conversion_interval = 31250;
224  break;
225 
226  case 3: /* SF10/b (50m 32Hz) */
227  _min_distance = 0.01f;
228  _max_distance = 50.0f;
229  _conversion_interval = 31250;
230  break;
231 
232  case 4: /* SF10/c (100m 16Hz) */
233  _min_distance = 0.01f;
234  _max_distance = 100.0f;
235  _conversion_interval = 62500;
236  break;
237 
238  case 5:
239  /* SF11/c (120m 20Hz) */
240  _min_distance = 0.01f;
241  _max_distance = 120.0f;
242  _conversion_interval = 50000;
243  break;
244 
245  default:
246  PX4_ERR("invalid HW model %d.", hw_model);
247  return -1;
248  }
249 
250  /* status */
251  int ret = 0;
252 
253  do { /* create a scope to handle exit conditions using break */
254 
255  /* do regular cdev init */
256  ret = CDev::init();
257 
258  if (ret != OK) { break; }
259 
260  /* allocate basic report buffers */
261  _reports = new ringbuffer::RingBuffer(2, sizeof(distance_sensor_s));
262 
263  if (_reports == nullptr) {
264  PX4_ERR("alloc failed");
265  ret = -1;
266  break;
267  }
268 
270 
271  /* get a publish handle on the range finder topic */
272  struct distance_sensor_s ds_report = {};
273 
274  _distance_sensor_topic = orb_advertise_multi(ORB_ID(distance_sensor), &ds_report,
276 
277  if (_distance_sensor_topic == nullptr) {
278  PX4_ERR("failed to create distance_sensor object");
279  }
280 
281  } while (0);
282 
283  return ret;
284 }
285 
286 void
288 {
289  _min_distance = min;
290 }
291 
292 void
294 {
295  _max_distance = max;
296 }
297 
298 float
300 {
301  return _min_distance;
302 }
303 
304 float
306 {
307  return _max_distance;
308 }
309 
310 int
311 SF0X::ioctl(device::file_t *filp, int cmd, unsigned long arg)
312 {
313  switch (cmd) {
314 
315  case SENSORIOCSPOLLRATE: {
316  switch (arg) {
317 
318  /* zero would be bad */
319  case 0:
320  return -EINVAL;
321 
322  /* set default polling rate */
324  /* do we need to start internal polling? */
325  bool want_start = (_measure_interval == 0);
326 
327  /* set interval for next measurement to minimum legal value */
329 
330  /* if we need to start the poll state machine, do it */
331  if (want_start) {
332  start();
333  }
334 
335  return OK;
336  }
337 
338  /* adjust to a legal polling interval in Hz */
339  default: {
340 
341  /* do we need to start internal polling? */
342  bool want_start = (_measure_interval == 0);
343 
344  /* convert hz to tick interval via microseconds */
345  int interval = (1000000 / arg);
346 
347  /* check against maximum rate */
348  if (interval < (_conversion_interval)) {
349  return -EINVAL;
350  }
351 
352  /* update interval for next measurement */
353  _measure_interval = interval;
354 
355  /* if we need to start the poll state machine, do it */
356  if (want_start) {
357  start();
358  }
359 
360  return OK;
361  }
362  }
363  }
364 
365  default:
366  /* give it to the superclass */
367  return CDev::ioctl(filp, cmd, arg);
368  }
369 }
370 
371 ssize_t
372 SF0X::read(device::file_t *filp, char *buffer, size_t buflen)
373 {
374  unsigned count = buflen / sizeof(struct distance_sensor_s);
375  struct distance_sensor_s *rbuf = reinterpret_cast<struct distance_sensor_s *>(buffer);
376  int ret = 0;
377 
378  /* buffer must be large enough */
379  if (count < 1) {
380  return -ENOSPC;
381  }
382 
383  /* if automatic measurement is enabled */
384  if (_measure_interval > 0) {
385 
386  /*
387  * While there is space in the caller's buffer, and reports, copy them.
388  * Note that we may be pre-empted by the workq thread while we are doing this;
389  * we are careful to avoid racing with them.
390  */
391  while (count--) {
392  if (_reports->get(rbuf)) {
393  ret += sizeof(*rbuf);
394  rbuf++;
395  }
396  }
397 
398  /* if there was no data, warn the caller */
399  return ret ? ret : -EAGAIN;
400  }
401 
402  /* manual measurement - run one conversion */
403  do {
404  _reports->flush();
405 
406  /* trigger a measurement */
407  if (OK != measure()) {
408  ret = -EIO;
409  break;
410  }
411 
412  /* wait for it to complete */
413  px4_usleep(_conversion_interval);
414 
415  /* run the collection phase */
416  if (OK != collect()) {
417  ret = -EIO;
418  break;
419  }
420 
421  /* state machine will have generated a report, copy it out */
422  if (_reports->get(rbuf)) {
423  ret = sizeof(*rbuf);
424  }
425 
426  } while (0);
427 
428  return ret;
429 }
430 
431 int
433 {
434  int ret;
435 
436  /*
437  * Send the command to begin a measurement.
438  */
439  char cmd = SF0X_TAKE_RANGE_REG;
440  ret = ::write(_fd, &cmd, 1);
441 
442  if (ret != sizeof(cmd)) {
444  PX4_DEBUG("write fail %d", ret);
445  return ret;
446  }
447 
448  ret = OK;
449 
450  return ret;
451 }
452 
453 int
455 {
457 
458  /* clear buffer if last read was too long ago */
459  int64_t read_elapsed = hrt_elapsed_time(&_last_read);
460 
461  /* the buffer for read chars is buflen minus null termination */
462  char readbuf[sizeof(_linebuf)];
463  unsigned readlen = sizeof(readbuf) - 1;
464 
465  /* read from the sensor (uart buffer) */
466  int ret = ::read(_fd, &readbuf[0], readlen);
467 
468  if (ret < 0) {
469  PX4_DEBUG("read err: %d", ret);
472 
473  /* only throw an error if we time out */
474  if (read_elapsed > (_conversion_interval * 2)) {
475  return ret;
476 
477  } else {
478  return -EAGAIN;
479  }
480 
481  } else if (ret == 0) {
482  return -EAGAIN;
483  }
484 
486 
487  float distance_m = -1.0f;
488  bool valid = false;
489 
490  for (int i = 0; i < ret; i++) {
491  if (OK == sf0x_parser(readbuf[i], _linebuf, &_linebuf_index, &_parse_state, &distance_m)) {
492  valid = true;
493  }
494  }
495 
496  if (!valid) {
497  return -EAGAIN;
498  }
499 
500  PX4_DEBUG("val (float): %8.4f, raw: %s, valid: %s", (double)distance_m, _linebuf, ((valid) ? "OK" : "NO"));
501 
502  struct distance_sensor_s report;
503 
504  report.timestamp = hrt_absolute_time();
505  report.type = distance_sensor_s::MAV_DISTANCE_SENSOR_LASER;
506  report.orientation = _rotation;
507  report.current_distance = distance_m;
510  report.variance = 0.0f;
511  report.signal_quality = -1;
512  /* TODO: set proper ID */
513  report.id = 0;
514 
515  /* publish it */
516  orb_publish(ORB_ID(distance_sensor), _distance_sensor_topic, &report);
517 
518  _reports->force(&report);
519 
520  /* notify anyone waiting for data */
521  poll_notify(POLLIN);
522 
523  ret = OK;
524 
526  return ret;
527 }
528 
529 void
531 {
532  /* reset the report ring and state machine */
533  _collect_phase = false;
534  _reports->flush();
535 
536  /* schedule a cycle to start things */
537  ScheduleNow();
538 }
539 
540 void
542 {
543  ScheduleClear();
544 }
545 
546 void
548 {
549  /* fds initialized? */
550  if (_fd < 0) {
551  /* open fd */
552  _fd = ::open(_port, O_RDWR | O_NOCTTY | O_NONBLOCK);
553 
554  if (_fd < 0) {
555  PX4_ERR("open failed (%i)", errno);
556  return;
557  }
558 
559  struct termios uart_config;
560 
561  int termios_state;
562 
563  /* fill the struct for the new configuration */
564  tcgetattr(_fd, &uart_config);
565 
566  /* clear ONLCR flag (which appends a CR for every LF) */
567  uart_config.c_oflag &= ~ONLCR;
568 
569  /* no parity, one stop bit */
570  uart_config.c_cflag &= ~(CSTOPB | PARENB);
571 
572  /* if distance sensor model is SF11/C, then set baudrate 115200, else 9600 */
573  int hw_model;
574 
575  param_get(param_find("SENS_EN_SF0X"), &hw_model);
576 
577  unsigned speed;
578 
579  if (hw_model == 5) {
580  speed = B115200;
581 
582  } else {
583  speed = B9600;
584  }
585 
586  /* set baud rate */
587  if ((termios_state = cfsetispeed(&uart_config, speed)) < 0) {
588  PX4_ERR("CFG: %d ISPD", termios_state);
589  }
590 
591  if ((termios_state = cfsetospeed(&uart_config, speed)) < 0) {
592  PX4_ERR("CFG: %d OSPD", termios_state);
593  }
594 
595  if ((termios_state = tcsetattr(_fd, TCSANOW, &uart_config)) < 0) {
596  PX4_ERR("baud %d ATTR", termios_state);
597  }
598  }
599 
600  /* collection phase? */
601  if (_collect_phase) {
602 
603  /* perform collection */
604  int collect_ret = collect();
605 
606  if (collect_ret == -EAGAIN) {
607  /* reschedule to grab the missing bits, time to transmit 8 bytes @ 9600 bps */
608  ScheduleDelayed(1042 * 8);
609 
610  return;
611  }
612 
613  if (OK != collect_ret) {
614 
615  /* we know the sensor needs about four seconds to initialize */
616  if (hrt_absolute_time() > 5 * 1000 * 1000LL && _consecutive_fail_count < 5) {
617  PX4_ERR("collection error #%u", _consecutive_fail_count);
618  }
619 
621 
622  /* restart the measurement state machine */
623  start();
624  return;
625 
626  } else {
627  /* apparently success */
629  }
630 
631  /* next phase is measurement */
632  _collect_phase = false;
633 
634  /*
635  * Is there a collect->measure gap?
636  */
638 
639  /* schedule a fresh cycle call when we are ready to measure again */
640  ScheduleDelayed(_measure_interval - _conversion_interval);
641 
642  return;
643  }
644  }
645 
646  /* measurement phase */
647  if (OK != measure()) {
648  PX4_DEBUG("measure error");
649  }
650 
651  /* next phase is collection */
652  _collect_phase = true;
653 
654  /* schedule a fresh cycle call when the measurement is done */
655  ScheduleDelayed(_conversion_interval);
656 }
657 
658 void
660 {
663  printf("poll interval: %d\n", _measure_interval);
664  _reports->print_info("report queue");
665 }
666 
667 /**
668  * Local functions in support of the shell command.
669  */
670 namespace sf0x
671 {
672 
674 
675 int start(const char *port, uint8_t rotation);
676 int stop();
677 int test();
678 int reset();
679 int info();
680 
681 /**
682  * Start the driver.
683  */
684 int
685 start(const char *port, uint8_t rotation)
686 {
687  int fd;
688 
689  if (g_dev != nullptr) {
690  PX4_WARN("already started");
691  return -1;
692  }
693 
694  /* create the driver */
695  g_dev = new SF0X(port, rotation);
696 
697  if (g_dev == nullptr) {
698  goto fail;
699  }
700 
701  if (OK != g_dev->init()) {
702  goto fail;
703  }
704 
705  /* set the poll rate to default, starts automatic data collection */
707 
708  if (fd < 0) {
709  PX4_ERR("device open fail (%i)", errno);
710  goto fail;
711  }
712 
714  goto fail;
715  }
716 
717  return 0;
718 
719 fail:
720 
721  if (g_dev != nullptr) {
722  delete g_dev;
723  g_dev = nullptr;
724  }
725 
726  return -1;
727 }
728 
729 /**
730  * Stop the driver
731  */
732 int stop()
733 {
734  if (g_dev != nullptr) {
735  delete g_dev;
736  g_dev = nullptr;
737 
738  } else {
739  return -1;
740  }
741 
742  return 0;
743 }
744 
745 /**
746  * Perform some basic functional tests on the driver;
747  * make sure we can collect data from the sensor in polled
748  * and automatic modes.
749  */
750 int
752 {
753  struct distance_sensor_s report;
754  ssize_t sz;
755 
756  int fd = open(RANGE_FINDER0_DEVICE_PATH, O_RDONLY);
757 
758  if (fd < 0) {
759  PX4_ERR("%s open failed (try 'sf0x start' if the driver is not running", RANGE_FINDER0_DEVICE_PATH);
760  return -1;
761  }
762 
763  /* do a simple demand read */
764  sz = read(fd, &report, sizeof(report));
765 
766  if (sz != sizeof(report)) {
767  PX4_ERR("immediate read failed");
768  return -1;
769  }
770 
771  print_message(report);
772 
773  /* start the sensor polling at 2 Hz rate */
774  if (OK != ioctl(fd, SENSORIOCSPOLLRATE, 2)) {
775  PX4_ERR("failed to set 2Hz poll rate");
776  return -1;
777  }
778 
779  /* read the sensor 5x and report each value */
780  for (unsigned i = 0; i < 5; i++) {
781  struct pollfd fds;
782 
783  /* wait for data to be ready */
784  fds.fd = fd;
785  fds.events = POLLIN;
786  int ret = poll(&fds, 1, 2000);
787 
788  if (ret != 1) {
789  PX4_ERR("timed out");
790  break;
791  }
792 
793  /* now go get it */
794  sz = read(fd, &report, sizeof(report));
795 
796  if (sz != sizeof(report)) {
797  PX4_ERR("read failed: got %zi vs exp. %zu", sz, sizeof(report));
798  break;
799  }
800 
801  print_message(report);
802  }
803 
804  /* reset the sensor polling to the default rate */
806  PX4_ERR("ioctl SENSORIOCSPOLLRATE failed");
807  return -1;
808  }
809 
810  return 0;
811 }
812 
813 /**
814  * Reset the driver.
815  */
816 int
818 {
819  int fd = open(RANGE_FINDER0_DEVICE_PATH, O_RDONLY);
820 
821  if (fd < 0) {
822  PX4_ERR("open failed (%i)", errno);
823  return -1;
824  }
825 
826  if (ioctl(fd, SENSORIOCRESET, 0) < 0) {
827  PX4_ERR("driver reset failed");
828  return -1;
829  }
830 
832  PX4_ERR("driver poll restart failed");
833  return -1;
834  }
835 
836  return 0;
837 }
838 
839 /**
840  * Print a little info about the driver.
841  */
842 int
844 {
845  if (g_dev == nullptr) {
846  PX4_ERR("driver not running");
847  return -1;
848  }
849 
850  printf("state @ %p\n", g_dev);
851  g_dev->print_info();
852 
853  return 0;
854 }
855 
856 } // namespace
857 
858 int
859 sf0x_main(int argc, char *argv[])
860 {
861  uint8_t rotation = distance_sensor_s::ROTATION_DOWNWARD_FACING;
862  const char *device_path = SF0X_DEFAULT_PORT;
863  int ch;
864  int myoptind = 1;
865  const char *myoptarg = nullptr;
866 
867  while ((ch = px4_getopt(argc, argv, "R:d:", &myoptind, &myoptarg)) != EOF) {
868  switch (ch) {
869  case 'R':
870  rotation = (uint8_t)atoi(myoptarg);
871  break;
872 
873  case 'd':
874  device_path = myoptarg;
875  break;
876 
877  default:
878  PX4_WARN("Unknown option!");
879  return -1;
880  }
881  }
882 
883  if (myoptind >= argc) {
884  goto out_error;
885  }
886 
887  /*
888  * Start/load the driver.
889  */
890  if (!strcmp(argv[myoptind], "start")) {
891  return sf0x::start(device_path, rotation);
892  }
893 
894  /*
895  * Stop the driver
896  */
897  if (!strcmp(argv[myoptind], "stop")) {
898  return sf0x::stop();
899  }
900 
901  /*
902  * Test the driver/device.
903  */
904  if (!strcmp(argv[myoptind], "test")) {
905  return sf0x::test();
906  }
907 
908  /*
909  * Reset the driver.
910  */
911  if (!strcmp(argv[myoptind], "reset")) {
912  return sf0x::reset();
913  }
914 
915  /*
916  * Print driver information.
917  */
918  if (!strcmp(argv[myoptind], "info") || !strcmp(argv[myoptind], "status")) {
919  return sf0x::info();
920  }
921 
922 out_error:
923  PX4_ERR("unrecognized command, try 'start', 'test', 'reset' or 'info'");
924  return -1;
925 }
Definition: sf0x.cpp:80
unsigned _linebuf_index
Definition: sf0x.cpp:107
unsigned _consecutive_fail_count
Definition: sf0x.cpp:116
#define RANGE_FINDER_BASE_DEVICE_PATH
virtual int open(file_t *filep)
Handle an open of the device.
Definition: CDev.cpp:141
float _min_distance
Definition: sf0x.cpp:99
measure the time elapsed performing an event
Definition: perf_counter.h:56
orb_advert_t _distance_sensor_topic
Definition: sf0x.cpp:114
void print_info()
Diagnostics - print some basic information about the driver.
Definition: sf0x.cpp:659
int _measure_interval
Definition: sf0x.cpp:103
__EXPORT int param_get(param_t param, void *val)
Copy the value of a parameter.
Definition: parameters.cpp:589
API for the uORB lightweight object broker.
int _conversion_interval
Definition: sf0x.cpp:101
virtual int register_class_devname(const char *class_devname)
Register a class device name, automatically adding device class instance suffix if need be...
Definition: CDev.cpp:78
int test()
Perform some basic functional tests on the driver; make sure we can collect data from the sensor in p...
Definition: sf0x.cpp:751
int reset()
Reset the driver.
Definition: sf0x.cpp:817
void Run() override
Perform a poll cycle; collect from the previous measurement and start a new one.
Definition: sf0x.cpp:547
#define SENSOR_POLLRATE_DEFAULT
poll at driver normal rate
Definition: drv_sensor.h:136
int sf0x_parser(char c, char *parserbuf, unsigned *parserbuf_index, enum SF0X_PARSE_STATE *state, float *dist)
Definition: sf0x_parser.cpp:61
Definition: I2C.hpp:51
int measure()
Definition: sf0x.cpp:432
float get_minimum_distance()
Definition: sf0x.cpp:299
SF0X * g_dev
Definition: sf0x.cpp:673
float get_maximum_distance()
Definition: sf0x.cpp:305
float _max_distance
Definition: sf0x.cpp:100
ringbuffer::RingBuffer * _reports
Definition: sf0x.cpp:102
count the number of times an event occurs
Definition: perf_counter.h:55
void start()
Initialise the automatic measurement state machine and start it.
Definition: sf0x.cpp:530
int start(const char *port, uint8_t rotation)
Start the driver.
Definition: sf0x.cpp:685
High-resolution timer with callouts and timekeeping.
int stop()
Stop the driver.
Definition: sf0x.cpp:732
perf_counter_t _comms_errors
Definition: sf0x.cpp:119
Global flash based parameter store.
virtual void poll_notify(pollevent_t events)
Report new poll events.
Definition: CDev.cpp:330
#define SENSORIOCSPOLLRATE
Set the driver polling rate to (arg) Hz, or one of the SENSOR_POLLRATE constants. ...
Definition: drv_sensor.h:134
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
Definition: uORB.h:87
uint8_t _rotation
Definition: sf0x.cpp:98
SF0X(const char *port=SF0X_DEFAULT_PORT, uint8_t rotation=distance_sensor_s::ROTATION_DOWNWARD_FACING)
Definition: sf0x.cpp:159
int collect()
Definition: sf0x.cpp:454
void perf_count(perf_counter_t handle)
Count a performance event.
#define SF0X_DEFAULT_PORT
Definition: sf0x.cpp:78
Abstract class for any character device.
Definition: CDev.hpp:58
Header common to all counters.
void set_minimum_distance(float min)
Set the min and max distance thresholds if you want the end points of the sensors range to be brought...
Definition: sf0x.cpp:287
void perf_free(perf_counter_t handle)
Free a counter.
void init()
Activates/configures the hardware registers.
char _linebuf[10]
Definition: sf0x.cpp:106
virtual int unregister_class_devname(const char *class_devname, unsigned class_instance)
Register a class device name, automatically adding device class instance suffix if need be...
Definition: CDev.cpp:109
#define perf_alloc(a, b)
Definition: px4io.h:59
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
static hrt_abstime hrt_elapsed_time(const hrt_abstime *then)
Compute the delta between a timestamp taken in the past and now.
Definition: drv_hrt.h:102
int info()
Print a little info about the driver.
Definition: sf0x.cpp:843
void perf_end(perf_counter_t handle)
End a performance event.
virtual ~SF0X()
Definition: sf0x.cpp:188
void set_maximum_distance(float max)
Definition: sf0x.cpp:293
__BEGIN_DECLS typedef uint64_t hrt_abstime
Absolute time, in microsecond units.
Definition: drv_hrt.h:58
virtual int init() override
Definition: sf0x.cpp:207
virtual ssize_t write(file_t *filep, const char *buffer, size_t buflen)
Perform a write to the device.
Definition: CDev.hpp:123
__BEGIN_DECLS typedef void * orb_advert_t
ORB topic advertiser handle.
Definition: uORB.h:134
int fd
Definition: dataman.cpp:146
int orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void *data)
Definition: uORB.cpp:70
int _orb_class_instance
Definition: sf0x.cpp:112
constexpr _Tp min(_Tp a, _Tp b)
Definition: Limits.hpp:54
__EXPORT param_t param_find(const char *name)
Look up a parameter by name.
Definition: parameters.cpp:370
Local functions in support of the shell command.
Definition: sf0x.cpp:670
hrt_abstime _last_read
Definition: sf0x.cpp:109
virtual ssize_t read(device::file_t *filp, char *buffer, size_t buflen) override
Perform a read from the device.
Definition: sf0x.cpp:372
constexpr _Tp max(_Tp a, _Tp b)
Definition: Limits.hpp:60
enum SF0X_PARSE_STATE _parse_state
Definition: sf0x.cpp:108
__EXPORT int sf0x_main(int argc, char *argv[])
Definition: sf0x.cpp:859
void perf_print_counter(perf_counter_t handle)
Print one performance counter to stdout.
SF0X_PARSE_STATE
Definition: sf0x_parser.h:43
#define SENSORIOCRESET
Reset the sensor to its default configuration.
Definition: drv_sensor.h:141
Definition: bst.cpp:62
CDev(const char *devname)
Constructor.
Definition: CDev.cpp:50
perf_counter_t _sample_perf
Definition: sf0x.cpp:118
int _class_instance
Definition: sf0x.cpp:111
#define OK
Definition: uavcan_main.cpp:71
virtual int ioctl(device::file_t *filp, int cmd, unsigned long arg) override
Perform an ioctl operation on the device.
Definition: sf0x.cpp:311
int _fd
Definition: sf0x.cpp:105
bool _collect_phase
Definition: sf0x.cpp:104
orb_advert_t orb_advertise_multi(const struct orb_metadata *meta, const void *data, int *instance, int priority)
Definition: uORB.cpp:53
#define SF0X_TAKE_RANGE_REG
Definition: sf0x.cpp:75
#define RANGE_FINDER0_DEVICE_PATH
char _port[20]
Definition: sf0x.cpp:97
void perf_begin(perf_counter_t handle)
Begin a performance event.
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
void stop()
Stop the automatic measurement state machine.
Definition: sf0x.cpp:541
virtual int poll(file_t *filep, px4_pollfd_struct_t *fds, bool setup)
Perform a poll setup/teardown operation.
Definition: CDev.cpp:213
Performance measuring tools.