Skip to content

Commit 08ced78

Browse files
committed
Improve performance for indoors and auto exposure/gain, add more params.
1 parent 4a314cf commit 08ced78

8 files changed

Lines changed: 215 additions & 79 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,4 @@ xcode
4646
src/platforms/posix/px4_messages/
4747
src/platforms/posix-arm/px4_messages/
4848
src/platforms/qurt/px4_messages/
49+
*.ipynb_checkpoints

notebooks/flow_analysis.ipynb

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 1,
6+
"metadata": {
7+
"collapsed": false
8+
},
9+
"outputs": [
10+
{
11+
"name": "stdout",
12+
"output_type": "stream",
13+
"text": [
14+
"Using matplotlib backend: Qt5Agg\n",
15+
"Populating the interactive namespace from numpy and matplotlib\n"
16+
]
17+
}
18+
],
19+
"source": [
20+
"%pylab"
21+
]
22+
},
23+
{
24+
"cell_type": "code",
25+
"execution_count": 20,
26+
"metadata": {
27+
"collapsed": false
28+
},
29+
"outputs": [
30+
{
31+
"data": {
32+
"text/plain": [
33+
"183.23012438744959"
34+
]
35+
},
36+
"execution_count": 20,
37+
"metadata": {},
38+
"output_type": "execute_result"
39+
}
40+
],
41+
"source": [
42+
"s = 64 # image size\n",
43+
"win = 4 # search area, pixels\n",
44+
"vel = 1 # velocity\n",
45+
"d = 1 # distance above ground\n",
46+
"rate = 100 # hz\n",
47+
"\n",
48+
"fov = np.deg2rad(5)\n",
49+
"f = s/(2*(tan(fov/2))) # focal length, pixels\n",
50+
"x = win * d/f\n",
51+
"rate = vel/x #rate, hz\n",
52+
"rate"
53+
]
54+
}
55+
],
56+
"metadata": {
57+
"anaconda-cloud": {},
58+
"kernelspec": {
59+
"display_name": "Python [default]",
60+
"language": "python",
61+
"name": "python3"
62+
},
63+
"language_info": {
64+
"codemirror_mode": {
65+
"name": "ipython",
66+
"version": 3
67+
},
68+
"file_extension": ".py",
69+
"mimetype": "text/x-python",
70+
"name": "python",
71+
"nbconvert_exporter": "python",
72+
"pygments_lexer": "ipython3",
73+
"version": "3.5.2"
74+
}
75+
},
76+
"nbformat": 4,
77+
"nbformat_minor": 1
78+
}

src/include/settings.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
#define ONBOARD_PARAM_NAME_LENGTH 15
4141
#define BOTTOM_FLOW_IMAGE_HEIGHT 64
4242
#define BOTTOM_FLOW_IMAGE_WIDTH 64
43-
#define BOTTOM_FLOW_SEARCH_WINDOW_SIZE 4
43+
#define BOTTOM_FLOW_SEARCH_WINDOW_SIZE 8
4444

4545
/******************************************************************
4646
* ALL TYPE DEFINITIONS
@@ -139,9 +139,18 @@ enum global_param_id_t
139139
PARAM_BOTTOM_FLOW_GYRO_COMPENSATION,
140140
PARAM_BOTTOM_FLOW_LP_FILTERED,
141141
PARAM_BOTTOM_FLOW_WEIGHT_NEW,
142-
PARAM_BOTTOM_FLOW_SERIAL_THROTTLE_FACTOR,
142+
PARAM_BOTTOM_FLOW_PUB_RATE,
143143

144144
PARAM_SENSOR_POSITION,
145+
PARAM_GAIN_MAX,
146+
PARAM_EXPOSURE_MAX,
147+
PARAM_SHTR_W_1,
148+
PARAM_SHTR_W_2,
149+
PARAM_SHTR_W_TOT,
150+
PARAM_HDR,
151+
PARAM_AEC,
152+
PARAM_AGC,
153+
PARAM_BRIGHT,
145154
DEBUG_VARIABLE,
146155

147156
ONBOARD_PARAM_COUNT

src/modules/flow/communication.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,23 @@ void handle_mavlink_message(mavlink_channel_t chan,
273273
l3gd20_config();
274274
}
275275

276+
/* shutter/ exposure params */
277+
else if(i == PARAM_SHTR_W_1 ||
278+
i == PARAM_SHTR_W_2 ||
279+
i == PARAM_SHTR_W_TOT ||
280+
i == PARAM_EXPOSURE_MAX ||
281+
i == PARAM_HDR ||
282+
i == PARAM_AEC ||
283+
i == PARAM_AGC ||
284+
i == PARAM_BRIGHT ||
285+
i == PARAM_GAIN_MAX
286+
)
287+
{
288+
mt9v034_context_configuration();
289+
dma_reconfigure();
290+
buffer_reset();
291+
}
292+
276293
else
277294
{
278295
debug_int_message_buffer("Parameter received, param id =", i);

src/modules/flow/flow.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -501,23 +501,23 @@ uint8_t compute_flow(uint8_t *image1, uint8_t *image2, float x_rate, float y_rat
501501
/* create flow image if needed (image1 is not needed anymore)
502502
* -> can be used for debugging purpose
503503
*/
504-
// if (global_data.param[PARAM_USB_SEND_VIDEO] )//&& global_data.param[PARAM_VIDEO_USB_MODE] == FLOW_VIDEO)
505-
// {
506-
//
507-
// for (j = pixLo; j < pixHi; j += pixStep)
508-
// {
509-
// for (i = pixLo; i < pixHi; i += pixStep)
510-
// {
511-
//
512-
// uint32_t diff = compute_diff(image1, i, j, (uint16_t) global_data.param[PARAM_IMAGE_WIDTH]);
513-
// if (diff > global_data.param[PARAM_BOTTOM_FLOW_FEATURE_THRESHOLD])
514-
// {
515-
// image1[j * ((uint16_t) global_data.param[PARAM_IMAGE_WIDTH]) + i] = 255;
516-
// }
517-
//
518-
// }
519-
// }
520-
// }
504+
if (global_data.param[PARAM_USB_SEND_VIDEO] )//&& global_data.param[PARAM_VIDEO_USB_MODE] == FLOW_VIDEO)
505+
{
506+
507+
for (j = pixLo; j < pixHi; j += pixStep)
508+
{
509+
for (i = pixLo; i < pixHi; i += pixStep)
510+
{
511+
512+
uint32_t diff = compute_diff(image1, i, j, (uint16_t) global_data.param[PARAM_IMAGE_WIDTH]);
513+
if (diff > global_data.param[PARAM_BOTTOM_FLOW_FEATURE_THRESHOLD])
514+
{
515+
image1[j * ((uint16_t) global_data.param[PARAM_IMAGE_WIDTH]) + i] = 255;
516+
}
517+
518+
}
519+
}
520+
}
521521

522522
/* evaluate flow calculation */
523523
if (meancount > 10)

src/modules/flow/main.c

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ int main(void)
342342
static uint32_t integration_timespan = 0;
343343
static uint32_t lasttime = 0;
344344
uint32_t time_since_last_sonar_update= 0;
345+
uint32_t time_last_pub= 0;
345346

346347
uavcan_start();
347348
/* main loop */
@@ -438,6 +439,22 @@ int main(void)
438439
float flow_compx = pixel_flow_x / focal_length_px / (get_time_between_images() / 1000000.0f);
439440
float flow_compy = pixel_flow_y / focal_length_px / (get_time_between_images() / 1000000.0f);
440441

442+
if (qual > 0)
443+
{
444+
valid_frame_count++;
445+
446+
uint32_t deltatime = (get_boot_time_us() - lasttime);
447+
integration_timespan += deltatime;
448+
accumulated_flow_x += pixel_flow_y / focal_length_px * 1.0f; //rad axis swapped to align x flow around y axis
449+
accumulated_flow_y += pixel_flow_x / focal_length_px * -1.0f;//rad
450+
accumulated_gyro_x += x_rate * deltatime / 1000000.0f; //rad
451+
accumulated_gyro_y += y_rate * deltatime / 1000000.0f; //rad
452+
accumulated_gyro_z += z_rate * deltatime / 1000000.0f; //rad
453+
accumulated_framecount++;
454+
accumulated_quality += qual;
455+
}
456+
457+
441458
/* integrate velocity and output values only if distance is valid */
442459
if (distance_valid)
443460
{
@@ -451,17 +468,6 @@ int main(void)
451468
{
452469
velocity_x_sum += new_velocity_x;
453470
velocity_y_sum += new_velocity_y;
454-
valid_frame_count++;
455-
456-
uint32_t deltatime = (get_boot_time_us() - lasttime);
457-
integration_timespan += deltatime;
458-
accumulated_flow_x += pixel_flow_y / focal_length_px * 1.0f; //rad axis swapped to align x flow around y axis
459-
accumulated_flow_y += pixel_flow_x / focal_length_px * -1.0f;//rad
460-
accumulated_gyro_x += x_rate * deltatime / 1000000.0f; //rad
461-
accumulated_gyro_y += y_rate * deltatime / 1000000.0f; //rad
462-
accumulated_gyro_z += z_rate * deltatime / 1000000.0f; //rad
463-
accumulated_framecount++;
464-
accumulated_quality += qual;
465471

466472
/* lowpass velocity output */
467473
velocity_x_lp = global_data.param[PARAM_BOTTOM_FLOW_WEIGHT_NEW] * new_velocity_x +
@@ -533,8 +539,11 @@ int main(void)
533539
PROBE_3(true);
534540

535541
//serial mavlink + usb mavlink output throttled
536-
if (counter % (uint32_t)global_data.param[PARAM_BOTTOM_FLOW_SERIAL_THROTTLE_FACTOR] == 0)//throttling factor
542+
uint32_t now = get_boot_time_us();
543+
uint32_t time_since_last_pub = now - time_last_pub;
544+
if (time_since_last_pub > (1.0e6f/global_data.param[PARAM_BOTTOM_FLOW_PUB_RATE]))
537545
{
546+
time_last_pub = now;
538547

539548
float flow_comp_m_x = 0.0f;
540549
float flow_comp_m_y = 0.0f;
@@ -577,10 +586,9 @@ int main(void)
577586
lpos.x += ground_distance*accumulated_flow_x;
578587
lpos.y += ground_distance*accumulated_flow_y;
579588
lpos.z = -ground_distance;
580-
/* velocity not directly measured and not important for testing */
581-
lpos.vx = 0;
582-
lpos.vy = 0;
583-
lpos.vz = 0;
589+
lpos.vx = ground_distance*accumulated_flow_x/integration_timespan;
590+
lpos.vy = ground_distance*accumulated_flow_y/integration_timespan;
591+
lpos.vz = 0; // no direct measurement, just ignore
584592

585593
} else {
586594
/* toggling param allows user reset */
@@ -699,7 +707,7 @@ int main(void)
699707
uint16_t frame = 0;
700708
for (frame = 0; frame < image_size_send / MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN + 1; frame++)
701709
{
702-
mavlink_msg_encapsulated_data_send(MAVLINK_COMM_2, frame, &((uint8_t *) current_image)[frame * MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN]);
710+
mavlink_msg_encapsulated_data_send(MAVLINK_COMM_2, frame, &((uint8_t *) previous_image)[frame * MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN]);
703711
}
704712

705713
send_image_now = false;

src/modules/flow/mt9v034.c

Lines changed: 24 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,13 @@ void mt9v034_context_configuration(void)
7979
uint16_t new_height_context_b = FULL_IMAGE_COLUMN_SIZE * 4;
8080

8181
/* blanking settings */
82-
uint16_t new_hor_blanking_context_a = 709 + MINIMUM_HORIZONTAL_BLANKING;// 709 is minimum value without distortions
82+
uint16_t new_hor_blanking_context_a = 425 + MINIMUM_HORIZONTAL_BLANKING;// 709 is minimum value without distortions
8383
uint16_t new_ver_blanking_context_a = 10; // this value is the first without image errors (dark lines)
8484
uint16_t new_hor_blanking_context_b = MAX_IMAGE_WIDTH - new_width_context_b + MINIMUM_HORIZONTAL_BLANKING;
8585
if (new_hor_blanking_context_b < 800) {
8686
new_hor_blanking_context_b = 800;
8787
}
88-
uint16_t new_ver_blanking_context_b = 10;
88+
uint16_t new_ver_blanking_context_b = 5;
8989

9090

9191
/* Read Mode
@@ -109,51 +109,38 @@ void mt9v034_context_configuration(void)
109109
* so we set max on 64 (lines) = 0x40
110110
*/
111111
uint16_t min_exposure = 0x0001; // default
112-
uint16_t max_exposure = 0x01E0; // default
113-
uint16_t new_max_gain = 64; // VALID RANGE: 16-64 (default)
114112
uint16_t pixel_count = 4096; //64x64 take all pixels to estimate exposure time // VALID RANGE: 1-65535
115-
116-
uint16_t desired_brightness = 58; // default
117-
uint16_t resolution_ctrl = 0x0203; // default
118-
uint16_t hdr_enabled = 0x0100; // default
119-
uint16_t aec_agc_enabled = 0x0003; // default
120-
uint16_t coarse_sw1 = 0x01BB; // default from context A
121-
uint16_t coarse_sw2 = 0x01D9; // default from context A
122113
uint16_t shutter_width_ctrl = 0x0164; // default from context A
123-
uint16_t total_shutter_width = 0x01E0; // default from context A
124114
uint16_t aec_update_freq = 0x02; // default Number of frames to skip between changes in AEC VALID RANGE: 0-15
125115
uint16_t aec_low_pass = 0x01; // default VALID RANGE: 0-2
126116
uint16_t agc_update_freq = 0x02; // default Number of frames to skip between changes in AGC VALID RANGE: 0-15
127117
uint16_t agc_low_pass = 0x02; // default VALID RANGE: 0-2
128118

119+
uint16_t resolution_ctrl = 0x0303; // 12 bit adc for low light
120+
uint16_t max_gain = global_data.param[PARAM_GAIN_MAX];
121+
uint16_t max_exposure = global_data.param[PARAM_EXPOSURE_MAX];
122+
uint16_t coarse_sw1 = global_data.param[PARAM_SHTR_W_1];
123+
uint16_t coarse_sw2 = global_data.param[PARAM_SHTR_W_2];
124+
uint16_t total_shutter_width = global_data.param[PARAM_SHTR_W_TOT];
125+
uint16_t hdr_enabled = 0x0000;
126+
bool hdr_enable_flag = global_data.param[PARAM_HDR] > 0;
127+
if (hdr_enable_flag) {
128+
hdr_enabled = 0x0100;
129+
}
129130

130-
if (FLOAT_AS_BOOL(global_data.param[PARAM_IMAGE_LOW_LIGHT]))
131-
{
132-
min_exposure = 0x0001;
133-
max_exposure = 0x0040;
134-
desired_brightness = 58; // VALID RANGE: 8-64
135-
resolution_ctrl = 0x0202;//10 bit linear
136-
hdr_enabled = 0x0000; // off
137-
aec_agc_enabled = 0x0303; // on
138-
coarse_sw1 = 0x01BB; // default from context A
139-
coarse_sw2 = 0x01D9; // default from context A
140-
shutter_width_ctrl = 0x0164; // default from context A
141-
total_shutter_width = 0x01E0; // default from context A
131+
bool aec_enable_flag = global_data.param[PARAM_AEC] > 0;
132+
uint16_t aec_agc_enabled = 0x0000;
133+
if (aec_enable_flag) {
134+
aec_agc_enabled |= (1 << 0);
142135
}
143-
else
144-
{
145-
min_exposure = 0x0001;
146-
max_exposure = 0x0080;
147-
desired_brightness = 16; // VALID RANGE: 8-64
148-
resolution_ctrl = 0x0202;//10bit linear
149-
hdr_enabled = 0x0000; // off
150-
aec_agc_enabled = 0x0303; // on
151-
coarse_sw1 = 0x01BB; // default from context A
152-
coarse_sw2 = 0x01D9; // default from context A
153-
shutter_width_ctrl = 0x0164; // default from context A
154-
total_shutter_width = 0x01E0; // default from context A
136+
137+
bool agc_enable_flag = global_data.param[PARAM_AGC] > 0;
138+
if (agc_enable_flag) {
139+
aec_agc_enabled |= (1 << 1);
155140
}
156141

142+
uint16_t desired_brightness = global_data.param[PARAM_BRIGHT];
143+
157144
uint16_t row_noise_correction = 0x0000; // default
158145
uint16_t test_data = 0x0000; // default
159146

@@ -216,7 +203,7 @@ void mt9v034_context_configuration(void)
216203
mt9v034_WriteReg16(MTV_HDR_ENABLE_REG, hdr_enabled); // disable HDR on both contexts
217204
mt9v034_WriteReg16(MTV_MIN_EXPOSURE_REG, min_exposure);
218205
mt9v034_WriteReg16(MTV_MAX_EXPOSURE_REG, max_exposure);
219-
mt9v034_WriteReg16(MTV_MAX_GAIN_REG, new_max_gain);
206+
mt9v034_WriteReg16(MTV_MAX_GAIN_REG, max_gain);
220207
mt9v034_WriteReg16(MTV_AGC_AEC_PIXEL_COUNT_REG, pixel_count);
221208
mt9v034_WriteReg16(MTV_AGC_AEC_DESIRED_BIN_REG, desired_brightness);
222209
mt9v034_WriteReg16(MTV_ADC_RES_CTRL_REG, resolution_ctrl); // here is the way to regulate darkness :)

0 commit comments

Comments
 (0)