-
Notifications
You must be signed in to change notification settings - Fork 343
Improve flow quality #90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
6feb336
87bee29
11a9616
1263206
30eb3d5
f0771ee
dd01d8d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -251,35 +251,47 @@ void dma_copy_image_buffers(uint8_t ** current_image, uint8_t ** previous_image, | |
| *current_image = *previous_image; | ||
| *previous_image = tmp_image; | ||
|
|
||
| TODO(NB dma_copy_image_buffers is calling uavcan_run()); | ||
|
|
||
| /* wait for new image if needed */ | ||
| while(image_counter < image_step) { | ||
| PROBE_1(false); | ||
| uavcan_run(); | ||
| PROBE_1(true); | ||
| } | ||
| while(image_counter < image_step); | ||
|
|
||
| image_counter = 0; | ||
|
|
||
| /* time between images */ | ||
| time_between_images = time_between_next_images; | ||
|
|
||
| uint8_t *source = NULL; | ||
|
|
||
| /* copy image */ | ||
| if (dcmi_image_buffer_unused == 1) | ||
| { | ||
| for (uint16_t pixel = 0; pixel < image_size; pixel++) | ||
| (*current_image)[pixel] = (uint8_t)(dcmi_image_buffer_8bit_1[pixel]); | ||
| if (dcmi_image_buffer_unused == 1) { | ||
| source = dcmi_image_buffer_8bit_1; | ||
| } else if (dcmi_image_buffer_unused == 2) { | ||
| source = dcmi_image_buffer_8bit_2; | ||
| } else { | ||
| source = dcmi_image_buffer_8bit_3; | ||
| } | ||
| else if (dcmi_image_buffer_unused == 2) | ||
| { | ||
| for (uint16_t pixel = 0; pixel < image_size; pixel++) | ||
| (*current_image)[pixel] = (uint8_t)(dcmi_image_buffer_8bit_2[pixel]); | ||
| } | ||
| else | ||
| { | ||
| for (uint16_t pixel = 0; pixel < image_size; pixel++) | ||
| (*current_image)[pixel] = (uint8_t)(dcmi_image_buffer_8bit_3[pixel]); | ||
|
|
||
| for (uint16_t pixel = 0; pixel < image_size; pixel++) | ||
| (*current_image)[pixel] = source[pixel]; | ||
| } | ||
|
|
||
| void whitened_image(uint8_t *source, uint8_t *dest, uint16_t image_size) { | ||
| double sum = 0.0; | ||
|
||
| for (uint16_t pixel = 0; pixel < image_size; pixel++) | ||
| sum += source[pixel]; | ||
| double mean = sum / image_size; | ||
| double rss = 0.0; | ||
| for (uint16_t pixel = 0; pixel < image_size; pixel++) | ||
| rss += pow(source[pixel] - mean, 2); | ||
|
||
| double stddev = sqrt(rss/(image_size - 1)); | ||
|
||
| dest[0] = stddev; | ||
|
|
||
| for (uint16_t pixel = 0; pixel < image_size; pixel++) { | ||
| double v = 127.0 + 32.0*(source[pixel] - mean)/stddev; | ||
| if (v < 0.0) | ||
| v = 0; | ||
| if (v > 255.0) | ||
| v = 255; | ||
| dest[pixel] = (uint8_t)v; | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -304,16 +316,11 @@ void send_calibration_image(uint8_t ** image_buffer_fast_1, uint8_t ** image_buf | |
| 100); | ||
|
|
||
| uint16_t frame = 0; | ||
| uint8_t image = 0; | ||
| uint8_t frame_buffer[MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN]; | ||
|
|
||
| for (int i = 0; i < FULL_IMAGE_SIZE * 4; i++) | ||
| { | ||
|
|
||
| if (i % FULL_IMAGE_SIZE == 0 && i != 0) | ||
| { | ||
| image++; | ||
| } | ||
| uint8_t image = i / FULL_IMAGE_SIZE; | ||
|
|
||
| if (i % MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN == 0 && i != 0) | ||
| { | ||
|
|
@@ -322,44 +329,39 @@ void send_calibration_image(uint8_t ** image_buffer_fast_1, uint8_t ** image_buf | |
| delay(2); | ||
| } | ||
|
|
||
| if (image == 0 ) | ||
| { | ||
| frame_buffer[i % MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN] = (uint8_t)(*image_buffer_fast_1)[i % FULL_IMAGE_SIZE]; | ||
| } | ||
| else if (image == 1 ) | ||
| { | ||
| frame_buffer[i % MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN] = (uint8_t)(*image_buffer_fast_2)[i % FULL_IMAGE_SIZE]; | ||
| } | ||
| else if (image == 2) | ||
| { | ||
| // The whole camera capture is stored in five parts: two buffers given | ||
| // as arguments, and three internal DMA buffers. | ||
| uint8_t *source; | ||
|
|
||
| if (image == 0) | ||
| source = *image_buffer_fast_1; | ||
| else if (image == 1) | ||
| source = *image_buffer_fast_2; | ||
| else if (image == 2) { | ||
| if (calibration_unused == 1) | ||
| frame_buffer[i % MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN] = dcmi_image_buffer_8bit_1[i % FULL_IMAGE_SIZE]; | ||
| source = dcmi_image_buffer_8bit_1; | ||
| else if (calibration_unused == 2) | ||
| frame_buffer[i % MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN] = dcmi_image_buffer_8bit_2[i % FULL_IMAGE_SIZE]; | ||
| source = dcmi_image_buffer_8bit_2; | ||
| else | ||
| frame_buffer[i % MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN] = dcmi_image_buffer_8bit_3[i % FULL_IMAGE_SIZE]; | ||
| } | ||
| else | ||
| { | ||
| if (calibration_used) | ||
| { | ||
| source = dcmi_image_buffer_8bit_3; | ||
| } else { | ||
| if (calibration_used) { | ||
| if (calibration_mem0 == 1) | ||
| frame_buffer[i % MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN] = dcmi_image_buffer_8bit_1[i % FULL_IMAGE_SIZE]; | ||
| source = dcmi_image_buffer_8bit_1; | ||
| else if (calibration_mem0 == 2) | ||
| frame_buffer[i % MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN] = dcmi_image_buffer_8bit_2[i % FULL_IMAGE_SIZE]; | ||
| source = dcmi_image_buffer_8bit_2; | ||
| else | ||
| frame_buffer[i % MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN] = dcmi_image_buffer_8bit_3[i % FULL_IMAGE_SIZE]; | ||
| } | ||
| else | ||
| { | ||
| source = dcmi_image_buffer_8bit_3; | ||
| } else { | ||
| if (calibration_mem1 == 1) | ||
| frame_buffer[i % MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN] = dcmi_image_buffer_8bit_1[i % FULL_IMAGE_SIZE]; | ||
| source = dcmi_image_buffer_8bit_1; | ||
| else if (calibration_mem1 == 2) | ||
| frame_buffer[i % MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN] = dcmi_image_buffer_8bit_2[i % FULL_IMAGE_SIZE]; | ||
| source = dcmi_image_buffer_8bit_2; | ||
| else | ||
| frame_buffer[i % MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN] = dcmi_image_buffer_8bit_3[i % FULL_IMAGE_SIZE]; | ||
| source = dcmi_image_buffer_8bit_3; | ||
| } | ||
| } | ||
| frame_buffer[i % MAVLINK_MSG_ENCAPSULATED_DATA_FIELD_DATA_LEN] = source[i % FULL_IMAGE_SIZE]; | ||
| } | ||
|
|
||
| mavlink_msg_encapsulated_data_send(MAVLINK_COMM_2, frame, frame_buffer); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -108,10 +108,10 @@ volatile uint32_t boot_time10_us = 0; | |
| #define TIMER_LPOS 8 | ||
| #define MS_TIMER_COUNT 100 /* steps in 10 microseconds ticks */ | ||
| #define LED_TIMER_COUNT 500 /* steps in milliseconds ticks */ | ||
| #define SONAR_TIMER_COUNT 100 /* steps in milliseconds ticks */ | ||
| #define SONAR_TIMER_COUNT 9999/* steps in milliseconds ticks */ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any particular reason you modified this? This gave very slow sonar update when I tested.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Whops, not intended to be included. I did this since we don't use this data at all, as the sonar is actually really bad.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you revert? |
||
| #define SYSTEM_STATE_COUNT 1000/* steps in milliseconds ticks */ | ||
| #define PARAMS_COUNT 100 /* steps in milliseconds ticks */ | ||
| #define LPOS_TIMER_COUNT 100 /* steps in milliseconds ticks */ | ||
| #define LPOS_TIMER_COUNT 100 /* steps in milliseconds ticks */ | ||
|
|
||
| static volatile unsigned timer[NTIMERS]; | ||
| static volatile unsigned timer_ms = MS_TIMER_COUNT; | ||
|
|
@@ -251,14 +251,14 @@ int main(void) | |
| LEDOff(LED_ACT); | ||
| LEDOff(LED_COM); | ||
| LEDOff(LED_ERR); | ||
| board_led_rgb(255,255,255, 1); | ||
| board_led_rgb( 0, 0,255, 0); | ||
| board_led_rgb( 0, 0, 0, 0); | ||
| board_led_rgb(255, 0, 0, 1); | ||
| board_led_rgb(255, 0, 0, 2); | ||
| board_led_rgb(255, 0, 0, 3); | ||
| board_led_rgb( 0,255, 0, 3); | ||
| board_led_rgb( 0, 0,255, 4); | ||
| board_led_rgb(255,255,255, 1); | ||
| board_led_rgb( 0, 0,255, 0); | ||
| board_led_rgb( 0, 0, 0, 0); | ||
| board_led_rgb(255, 0, 0, 1); | ||
| board_led_rgb(255, 0, 0, 2); | ||
| board_led_rgb(255, 0, 0, 3); | ||
| board_led_rgb( 0,255, 0, 3); | ||
| board_led_rgb( 0, 0,255, 4); | ||
|
|
||
| /* enable FPU on Cortex-M4F core */ | ||
| SCB_CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10 Full Access and set CP11 Full Access */ | ||
|
|
@@ -300,8 +300,8 @@ int main(void) | |
| /* usart config*/ | ||
| usart_init(); | ||
|
|
||
| /* i2c config*/ | ||
| i2c_init(); | ||
| /* i2c config*/ | ||
| i2c_init(); | ||
|
|
||
| /* sonar config*/ | ||
| float sonar_distance_filtered = 0.0f; // distance in meter | ||
|
|
@@ -347,9 +347,10 @@ int main(void) | |
| /* main loop */ | ||
| while (1) | ||
| { | ||
| PROBE_1(false); | ||
| uavcan_run(); | ||
| PROBE_1(true); | ||
| PROBE_1(false); | ||
| uavcan_run(); | ||
| PROBE_1(true); | ||
|
|
||
| /* reset flow buffers if needed */ | ||
| if(buffer_reset_needed) | ||
| { | ||
|
|
@@ -426,6 +427,7 @@ int main(void) | |
| { | ||
| /* copy recent image to faster ram */ | ||
| dma_copy_image_buffers(¤t_image, &previous_image, image_size, 1); | ||
| whitened_image(current_image, current_image, image_size); | ||
|
|
||
| /* compute optical flow */ | ||
| qual = compute_flow(previous_image, current_image, x_rate, y_rate, z_rate, &pixel_flow_x, &pixel_flow_y); | ||
|
|
@@ -499,20 +501,12 @@ int main(void) | |
|
|
||
| float ground_distance = 0.0f; | ||
|
|
||
| ground_distance = FLOAT_AS_BOOL(global_data.param[PARAM_SONAR_FILTERED]) ? sonar_distance_filtered : sonar_distance_raw; | ||
|
|
||
| if(FLOAT_AS_BOOL(global_data.param[PARAM_SONAR_FILTERED])) | ||
| { | ||
| ground_distance = sonar_distance_filtered; | ||
| } | ||
| else | ||
| { | ||
| ground_distance = sonar_distance_raw; | ||
| } | ||
|
|
||
| uavcan_define_export(i2c_data, legacy_12c_data_t, ccm); | ||
| uavcan_define_export(range_data, range_data_t, ccm); | ||
| uavcan_define_export(i2c_data, legacy_12c_data_t, ccm); | ||
| uavcan_define_export(range_data, range_data_t, ccm); | ||
| uavcan_timestamp_export(i2c_data); | ||
| uavcan_assign(range_data.time_stamp_utc, i2c_data.time_stamp_utc); | ||
| uavcan_assign(range_data.time_stamp_utc, i2c_data.time_stamp_utc); | ||
| //update I2C transmitbuffer | ||
| if(valid_frame_count>0) | ||
| { | ||
|
|
@@ -524,15 +518,15 @@ int main(void) | |
| update_TX_buffer(pixel_flow_x, pixel_flow_y, 0.0f, 0.0f, qual, | ||
| ground_distance, x_rate, y_rate, z_rate, gyro_temp, uavcan_use_export(i2c_data)); | ||
| } | ||
| PROBE_2(false); | ||
| uavcan_publish(range, 40, range_data); | ||
| PROBE_2(true); | ||
| PROBE_2(false); | ||
| uavcan_publish(range, 40, range_data); | ||
| PROBE_2(true); | ||
|
|
||
| PROBE_3(false); | ||
| uavcan_publish(flow, 40, i2c_data); | ||
| PROBE_3(true); | ||
| PROBE_3(false); | ||
| uavcan_publish(flow, 40, i2c_data); | ||
| PROBE_3(true); | ||
|
|
||
| //serial mavlink + usb mavlink output throttled | ||
| //serial mavlink + usb mavlink output throttled | ||
| if (counter % (uint32_t)global_data.param[PARAM_BOTTOM_FLOW_SERIAL_THROTTLE_FACTOR] == 0)//throttling factor | ||
| { | ||
|
|
||
|
|
@@ -577,7 +571,7 @@ int main(void) | |
| lpos.x += ground_distance*accumulated_flow_x; | ||
| lpos.y += ground_distance*accumulated_flow_y; | ||
| lpos.z = -ground_distance; | ||
| /* velocity not directly measured and not important for testing */ | ||
| /* velocity not directly measured and not important for testing */ | ||
| lpos.vx = 0; | ||
| lpos.vy = 0; | ||
| lpos.vz = 0; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I'm wondering how this compares to the auto gain and brightness controls within the camera firmware. Both pieces of software have the same goal, so you might just be eating more cpu here. You might want to check. But if your method is better than the whitening methods coded in the camera firmware, maybe you want to turn auto gain etc. off.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
http://www.onsemi.com/pub/Collateral/MT9V034-D.PDF