Skip to content

Commit 80134d2

Browse files
rmackay9LorenzMeier
authored andcommitted
IR-LOCK: rework driver (from jschall) (#5024)
* irlock: change output format to tangent of angles * irlock: put all targets in single struct * irlock: eliminate tanf function in constant
1 parent 71d150f commit 80134d2

File tree

2 files changed

+54
-39
lines changed

2 files changed

+54
-39
lines changed

src/drivers/drv_irlock.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,17 @@
4949

5050
#define IRLOCK_OBJECTS_MAX 5 /** up to 5 objects can be detected/reported **/
5151

52+
struct irlock_target_s {
53+
uint16_t signature; /** target signature **/
54+
float pos_x; /** x-axis distance from center of image to center of target in units of tan(theta) **/
55+
float pos_y; /** y-axis distance from center of image to center of target in units of tan(theta) **/
56+
float size_x; /** size of target along x-axis in units of tan(theta) **/
57+
float size_y; /** size of target along y-axis in units of tan(theta) **/
58+
};
59+
5260
/** irlock_s structure returned from read calls **/
5361
struct irlock_s {
5462
uint64_t timestamp; /** microseconds since system start **/
55-
uint16_t target_num; /** target number prioritised by size (largest is 0) **/
56-
float angle_x; /** x-axis angle in radians from center of image to center of target **/
57-
float angle_y; /** y-axis angle in radians from center of image to center of target **/
58-
float size_x; /** size in radians of target along x-axis **/
59-
float size_y; /** size in radians of target along y-axis **/
63+
uint8_t num_targets;
64+
struct irlock_target_s targets[IRLOCK_OBJECTS_MAX];
6065
};

src/drivers/irlock/irlock.cpp

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,20 @@
6767
#define IRLOCK_RESYNC 0x5500
6868
#define IRLOCK_ADJUST 0xAA
6969

70-
#define IRLOCK_CENTER_X 159 // the x-axis center pixel position
71-
#define IRLOCK_CENTER_Y 99 // the y-axis center pixel position
72-
#define IRLOCK_PIXELS_PER_RADIAN_X 307.9075f // x-axis pixel to radian scaler assuming 60deg FOV on x-axis
73-
#define IRLOCK_PIXELS_PER_RADIAN_Y 326.4713f // y-axis pixel to radian scaler assuming 35deg FOV on y-axis
70+
#define IRLOCK_RES_X 320
71+
#define IRLOCK_RES_Y 200
72+
73+
#define IRLOCK_CENTER_X (IRLOCK_RES_X/2) // the x-axis center pixel position
74+
#define IRLOCK_CENTER_Y (IRLOCK_RES_Y/2) // the y-axis center pixel position
75+
76+
#define IRLOCK_FOV_X (60.0f*M_PI_F/180.0f)
77+
#define IRLOCK_FOV_Y (35.0f*M_PI_F/180.0f)
78+
79+
#define IRLOCK_TAN_HALF_FOV_X 0.57735026919f // tan(0.5 * 60 * pi/180)
80+
#define IRLOCK_TAN_HALF_FOV_Y 0.31529878887f // tan(0.5 * 35 * pi/180)
81+
82+
#define IRLOCK_TAN_ANG_PER_PIXEL_X (2*IRLOCK_TAN_HALF_FOV_X/IRLOCK_RES_X)
83+
#define IRLOCK_TAN_ANG_PER_PIXEL_Y (2*IRLOCK_TAN_HALF_FOV_Y/IRLOCK_RES_Y)
7484

7585
#ifndef CONFIG_SCHED_WORKQUEUE
7686
# error This requires CONFIG_SCHED_WORKQUEUE.
@@ -107,7 +117,7 @@ class IRLOCK : public device::I2C
107117
int read_device();
108118
bool sync_device();
109119
int read_device_word(uint16_t *word);
110-
int read_device_block(struct irlock_s *block);
120+
int read_device_block(struct irlock_target_s *block);
111121

112122
/** internal variables **/
113123
ringbuffer::RingBuffer *_reports;
@@ -158,7 +168,7 @@ int IRLOCK::init()
158168
}
159169

160170
/** allocate buffer storing values read from sensor **/
161-
_reports = new ringbuffer::RingBuffer(IRLOCK_OBJECTS_MAX, sizeof(struct irlock_s));
171+
_reports = new ringbuffer::RingBuffer(2, sizeof(struct irlock_s));
162172

163173
if (_reports == nullptr) {
164174
return ENOTTY;
@@ -224,20 +234,20 @@ int IRLOCK::test()
224234
warnx("searching for object for 10 seconds");
225235

226236
/** read from sensor for 10 seconds **/
227-
struct irlock_s obj_report;
237+
struct irlock_s report;
228238
uint64_t start_time = hrt_absolute_time();
229239

230240
while ((hrt_absolute_time() - start_time) < 10000000) {
231-
232-
/** output all objects found **/
233-
while (_reports->count() > 0) {
234-
_reports->get(&obj_report);
235-
warnx("sig:%d x:%4.3f y:%4.3f width:%4.3f height:%4.3f",
236-
(int)obj_report.target_num,
237-
(double)obj_report.angle_x,
238-
(double)obj_report.angle_y,
239-
(double)obj_report.size_x,
240-
(double)obj_report.size_y);
241+
if (_reports->get(&report)) {
242+
/** output all objects found **/
243+
for (uint8_t i = 0; i < report.num_targets; i++) {
244+
warnx("sig:%d x:%4.3f y:%4.3f width:%4.3f height:%4.3f",
245+
(int)report.targets[i].signature,
246+
(double)report.targets[i].pos_x,
247+
(double)report.targets[i].pos_y,
248+
(double)report.targets[i].size_x,
249+
(double)report.targets[i].size_y);
250+
}
241251
}
242252

243253
/** sleep for 0.05 seconds **/
@@ -337,20 +347,22 @@ int IRLOCK::read_device()
337347
return -ENOTTY;
338348
}
339349

340-
/** now read blocks until sync stops, first flush stale queue data **/
341-
_reports->flush();
342-
int num_objects = 0;
350+
struct irlock_s report;
351+
352+
report.timestamp = hrt_absolute_time();
343353

344-
while (sync_device() && (num_objects < IRLOCK_OBJECTS_MAX)) {
345-
struct irlock_s block;
354+
report.num_targets = 0;
346355

347-
if (read_device_block(&block) != OK) {
356+
while (report.num_targets < IRLOCK_OBJECTS_MAX) {
357+
if (!sync_device() || read_device_block(&report.targets[report.num_targets]) != OK) {
348358
break;
349359
}
350360

351-
_reports->force(&block);
361+
report.num_targets++;
352362
}
353363

364+
_reports->force(&report);
365+
354366
return OK;
355367
}
356368

@@ -367,33 +379,31 @@ int IRLOCK::read_device_word(uint16_t *word)
367379
}
368380

369381
/** read a single block (a full frame) from sensor **/
370-
int IRLOCK::read_device_block(struct irlock_s *block)
382+
int IRLOCK::read_device_block(struct irlock_target_s *block)
371383
{
372384
uint8_t bytes[12];
373385
memset(bytes, 0, sizeof bytes);
374386

375387
int status = transfer(nullptr, 0, &bytes[0], 12);
376388
uint16_t checksum = bytes[1] << 8 | bytes[0];
377-
uint16_t target_num = bytes[3] << 8 | bytes[2];
389+
uint16_t signature = bytes[3] << 8 | bytes[2];
378390
uint16_t pixel_x = bytes[5] << 8 | bytes[4];
379391
uint16_t pixel_y = bytes[7] << 8 | bytes[6];
380392
uint16_t pixel_size_x = bytes[9] << 8 | bytes[8];
381393
uint16_t pixel_size_y = bytes[11] << 8 | bytes[10];
382394

383395
/** crc check **/
384-
if (target_num + pixel_x + pixel_y + pixel_size_x + pixel_size_y != checksum) {
396+
if (signature + pixel_x + pixel_y + pixel_size_x + pixel_size_y != checksum) {
385397
_read_failures++;
386398
return -EIO;
387399
}
388400

389401
/** convert to angles **/
390-
block->target_num = target_num;
391-
block->angle_x = (((float)(pixel_x - IRLOCK_CENTER_X)) / IRLOCK_PIXELS_PER_RADIAN_X);
392-
block->angle_y = (((float)(pixel_y - IRLOCK_CENTER_Y)) / IRLOCK_PIXELS_PER_RADIAN_Y);
393-
block->size_x = pixel_size_x / IRLOCK_PIXELS_PER_RADIAN_X;
394-
block->size_y = pixel_size_y / IRLOCK_PIXELS_PER_RADIAN_Y;
395-
396-
block->timestamp = hrt_absolute_time();
402+
block->signature = signature;
403+
block->pos_x = (pixel_x - IRLOCK_CENTER_X) * IRLOCK_TAN_ANG_PER_PIXEL_X;
404+
block->pos_y = (pixel_y - IRLOCK_CENTER_Y) * IRLOCK_TAN_ANG_PER_PIXEL_Y;
405+
block->size_x = pixel_size_x * IRLOCK_TAN_ANG_PER_PIXEL_X;
406+
block->size_y = pixel_size_y * IRLOCK_TAN_ANG_PER_PIXEL_Y;
397407
return status;
398408
}
399409

0 commit comments

Comments
 (0)