diff --git a/conf/modules/cv_opticflow.xml b/conf/modules/cv_opticflow.xml
index 808b556134b..af3f680a58e 100644
--- a/conf/modules/cv_opticflow.xml
+++ b/conf/modules/cv_opticflow.xml
@@ -43,16 +43,18 @@
-
+
+
+
diff --git a/sw/airborne/modules/computer_vision/cv/framerate.c b/sw/airborne/modules/computer_vision/cv/framerate.c
new file mode 100644
index 00000000000..4fc3b4e282c
--- /dev/null
+++ b/sw/airborne/modules/computer_vision/cv/framerate.c
@@ -0,0 +1,54 @@
+
+#include "std.h"
+#include "framerate.h"
+
+// Frame Rate (FPS)
+#include
+
+// local variables
+volatile long timestamp;
+struct timeval start_time;
+struct timeval end_time;
+
+#define USEC_PER_SEC 1000000L
+
+float FPS;
+
+static long time_elapsed(struct timeval *t1, struct timeval *t2)
+{
+ long sec, usec;
+ sec = t2->tv_sec - t1->tv_sec;
+ usec = t2->tv_usec - t1->tv_usec;
+ if (usec < 0) {
+ --sec;
+ usec = usec + USEC_PER_SEC;
+ }
+ return sec * USEC_PER_SEC + usec;
+}
+
+static void start_timer(void)
+{
+ gettimeofday(&start_time, NULL);
+}
+
+static long end_timer(void)
+{
+ gettimeofday(&end_time, NULL);
+ return time_elapsed(&start_time, &end_time);
+}
+
+
+void framerate_init(void) {
+ // Frame Rate Initialization
+ FPS = 0.0;
+ timestamp = 0;
+ start_timer();
+}
+
+void framerate_run(void) {
+ // FPS
+ timestamp = end_timer();
+ FPS = (float) 1000000 / (float)timestamp;
+ // printf("dt = %d, FPS = %f\n",timestamp, FPS);
+ start_timer();
+}
diff --git a/sw/airborne/modules/computer_vision/cv/framerate.h b/sw/airborne/modules/computer_vision/cv/framerate.h
new file mode 100644
index 00000000000..060811fff6d
--- /dev/null
+++ b/sw/airborne/modules/computer_vision/cv/framerate.h
@@ -0,0 +1,5 @@
+
+extern float FPS;
+
+void framerate_init(void);
+void framerate_run(void);
diff --git a/sw/airborne/modules/computer_vision/opticflow/hover_stabilization.c b/sw/airborne/modules/computer_vision/opticflow/hover_stabilization.c
index e3185b8f911..4dfee89e59b 100644
--- a/sw/airborne/modules/computer_vision/opticflow/hover_stabilization.c
+++ b/sw/airborne/modules/computer_vision/opticflow/hover_stabilization.c
@@ -29,11 +29,7 @@
// Own Header
#include "hover_stabilization.h"
-// Vision Data
-#include "visual_estimator.h"
-
// Stabilization
-//#include "stabilization.h"
#include "firmwares/rotorcraft/stabilization/stabilization_attitude.h"
#include "firmwares/rotorcraft/guidance/guidance_v.h"
#include "autopilot.h"
@@ -144,15 +140,12 @@ void init_hover_stabilization_onvision()
Vely_Int = 0;
}
-void run_hover_stabilization_onvision(void)
+void run_hover_stabilization_onvision(struct CVresults* vision )
{
- if (autopilot_mode == AP_MODE_MODULE) {
- run_opticflow_hover();
+ if (autopilot_mode != AP_MODE_MODULE) {
+ return;
}
-}
-void run_opticflow_hover(void)
-{
struct FloatVect3 V_body;
if (activate_opticflow_hover == TRUE) {
// Compute body velocities from ENU
@@ -161,9 +154,9 @@ void run_opticflow_hover(void)
float_quat_vmult(&V_body, q_n2b, vel_ned);
}
- if (flow_count) {
- Error_Velx = Velx - vision_desired_vx;
- Error_Vely = Vely - vision_desired_vy;
+ if (vision->flow_count) {
+ Error_Velx = vision->Velx - vision_desired_vx;
+ Error_Vely = vision->Vely - vision_desired_vy;
} else {
Error_Velx = 0;
Error_Vely = 0;
@@ -204,6 +197,6 @@ void run_opticflow_hover(void)
else if (cmd_euler.theta > CMD_OF_SAT) {cmd_euler.theta = CMD_OF_SAT; saturateY = 1;}
stabilization_attitude_set_rpy_setpoint_i(&cmd_euler);
- DOWNLINK_SEND_VISION_STABILIZATION(DefaultChannel, DefaultDevice, &Velx, &Vely, &Velx_Int,
+ DOWNLINK_SEND_VISION_STABILIZATION(DefaultChannel, DefaultDevice, &vision->Velx, &vision->Vely, &Velx_Int,
&Vely_Int, &cmd_euler.phi, &cmd_euler.theta);
}
diff --git a/sw/airborne/modules/computer_vision/opticflow/hover_stabilization.h b/sw/airborne/modules/computer_vision/opticflow/hover_stabilization.h
index 3f14b09f15c..285ac708649 100644
--- a/sw/airborne/modules/computer_vision/opticflow/hover_stabilization.h
+++ b/sw/airborne/modules/computer_vision/opticflow/hover_stabilization.h
@@ -30,6 +30,7 @@
#define HOVER_STABILIZATION_H_
#include
+#include "inter_thread_data.h"
// Controller module
@@ -46,7 +47,7 @@ extern void guidance_h_module_run(bool_t in_flight);
void init_hover_stabilization_onvision(void);
-void run_hover_stabilization_onvision(void);
+void run_hover_stabilization_onvision(struct CVresults *vision);
extern bool activate_opticflow_hover;
extern float vision_desired_vx;
diff --git a/sw/airborne/modules/computer_vision/opticflow/inter_thread_data.h b/sw/airborne/modules/computer_vision/opticflow/inter_thread_data.h
new file mode 100644
index 00000000000..512f75bb46b
--- /dev/null
+++ b/sw/airborne/modules/computer_vision/opticflow/inter_thread_data.h
@@ -0,0 +1,28 @@
+
+
+#ifndef _INTER_THREAD_DATA_H
+#define _INTER_THREAD_DATA_H
+
+
+// Inter-thread communication: Unix Socket
+
+// Data from thread to module
+struct CVresults {
+ int x;
+ int status;
+ float Velx;
+ float Vely;
+ int flow_count;
+};
+
+// Data from module to thread
+struct PPRZinfo {
+ int cnt;
+ float theta;
+ float phi;
+ float agl;
+};
+
+
+
+#endif
diff --git a/sw/airborne/modules/computer_vision/opticflow/opticflow_thread.c b/sw/airborne/modules/computer_vision/opticflow/opticflow_thread.c
new file mode 100644
index 00000000000..00d9a0f2759
--- /dev/null
+++ b/sw/airborne/modules/computer_vision/opticflow/opticflow_thread.c
@@ -0,0 +1,121 @@
+
+
+
+// Sockets
+#include
+#include
+#include
+#include
+
+#include "opticflow_thread.h"
+
+
+/////////////////////////////////////////////////////////////////////////
+// COMPUTER VISION THREAD
+
+// Video
+#include "v4l/video.h"
+#include "resize.h"
+
+// Payload Code
+#include "visual_estimator.h"
+
+// Downlink Video
+//#define DOWNLINK_VIDEO 1
+
+#ifdef DOWNLINK_VIDEO
+#include "encoding/jpeg.h"
+#include "encoding/rtp.h"
+#endif
+
+#include
+
+static volatile enum{RUN,EXIT} computer_vision_thread_command = RUN; /** request to close: set to 1 */
+
+void computervision_thread_request_exit(void) {
+ computer_vision_thread_command = 0;
+}
+
+void *computervision_thread_main(void *args)
+{
+ int thread_socket = *(int *) args;
+ int cnt = 0;
+
+ computer_vision_thread_command = RUN;
+
+ struct CVresults vision_results;
+ struct PPRZinfo autopilot_data;
+
+ // Video Input
+ struct vid_struct vid;
+ vid.device = (char *)"/dev/video2"; // video1 = front camera; video2 = bottom camera
+ vid.w = 320;
+ vid.h = 240;
+ vid.n_buffers = 4;
+
+ vision_results.status = 1;
+
+ if (video_init(&vid) < 0) {
+ printf("Error initialising video\n");
+ vision_results.status = -1;
+ return 0;
+ }
+
+ // Video Grabbing
+ struct img_struct *img_new = video_create_image(&vid);
+
+#ifdef DOWNLINK_VIDEO
+ // Video Compression
+ uint8_t *jpegbuf = (uint8_t *)malloc(vid.h * vid.w * 2);
+
+ // Network Transmit
+ struct UdpSocket *vsock;
+ //#define FMS_UNICAST 0
+ //#define FMS_BROADCAST 1
+ vsock = udp_socket("192.168.1.255", 5000, 5001, FMS_BROADCAST);
+#endif
+
+ // First Apply Settings before init
+ opticflow_plugin_init(vid.w, vid.h, &vision_results);
+
+ while (computer_vision_thread_command > 0) {
+ vision_results.status = 2;
+ video_grab_image(&vid, img_new);
+
+ // Get most recent State
+ int bytes_read = read(thread_socket, &autopilot_data, sizeof(autopilot_data));
+ if (bytes_read <= sizeof(autopilot_data)) {
+ if (bytes_read != 0) {
+ printf("Failed to read PPRZ info from socket.\n");
+ }
+ }
+
+ // Run Image Processing
+ opticflow_plugin_run(img_new->buf, &autopilot_data, &vision_results);
+
+ /* send results to main */
+ vision_results.x = cnt++;
+ int bytes_written = write(thread_socket, &vision_results, sizeof(vision_results));
+ if (bytes_written != sizeof(vision_results)){
+ perror("failed to write to socket.\n");
+ }
+
+
+#ifdef DOWNLINK_VIDEO
+ // JPEG encode the image:
+ uint32_t quality_factor = 10; //20 if no resize,
+ uint8_t dri_header = 0;
+ uint32_t image_format = FOUR_TWO_TWO; // format (in jpeg.h)
+ uint8_t *end = encode_image(small.buf, jpegbuf, quality_factor, image_format, small.w, small.h, dri_header);
+ uint32_t size = end - (jpegbuf);
+
+ printf("Sending an image ...%u\n", size);
+ uint32_t delta_t_per_frame = 0; // 0 = use drone clock
+ send_rtp_frame(vsock, jpegbuf, size, small.w, small.h, 0, quality_factor, dri_header, delta_t_per_frame);
+#endif
+ }
+ printf("Thread Closed\n");
+ video_close(&vid);
+ vision_results.status = -100;
+ return 0;
+}
diff --git a/sw/airborne/modules/computer_vision/opticflow/opticflow_thread.h b/sw/airborne/modules/computer_vision/opticflow/opticflow_thread.h
new file mode 100644
index 00000000000..eaa48a1d385
--- /dev/null
+++ b/sw/airborne/modules/computer_vision/opticflow/opticflow_thread.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 The Paparazzi Community
+ *
+ * This file is part of Paparazzi.
+ *
+ * Paparazzi is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * Paparazzi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Paparazzi; see the file COPYING. If not, see
+ * .
+ */
+
+/**
+ * @file modules/computer_vision/opticflow/opticflow_thread.c
+ * @brief computer vision thread
+ *
+ * Sensors from vertical camera and IMU of Parrot AR.Drone 2.0
+ */
+
+
+#include "std.h"
+
+void *computervision_thread_main(void *args); /* computer vision thread: should be given a pointer to a socketpair as argument */
+void computervision_thread_request_exit(void);
diff --git a/sw/airborne/modules/computer_vision/opticflow/visual_estimator.c b/sw/airborne/modules/computer_vision/opticflow/visual_estimator.c
index 3012b92ef6f..f69d8aa6b87 100644
--- a/sw/airborne/modules/computer_vision/opticflow/visual_estimator.c
+++ b/sw/airborne/modules/computer_vision/opticflow/visual_estimator.c
@@ -25,7 +25,10 @@
* Sensors from vertical camera and IMU of Parrot AR.Drone 2.0
*/
+// Warning: all this code is called form the Vision-Thread: do not access any autopilot data in here.
+
#include
+#include
#include
// Own Header
@@ -36,17 +39,7 @@
#include "opticflow/fast9/fastRosten.h"
// for FPS
-#include "modules/computer_vision/opticflow_module.h"
-
-// Paparazzi Data
-#include "state.h"
-#include "subsystems/abi.h"
-
-// Downlink
-#include "subsystems/datalink/downlink.h"
-
-// Timer
-#include
+#include "modules/computer_vision/cv/framerate.h"
// Image size set at init
unsigned int imgWidth, imgHeight;
@@ -71,7 +64,6 @@ int max_count = 25;
// Corner Tracking
int *new_x, *new_y, *status, *dx, *dy;
int error_opticflow;
-int flow_count = 0;
int remove_point;
int c;
int borderx = 24, bordery = 24;
@@ -84,30 +76,10 @@ float distance2, min_distance, min_distance2;
float curr_pitch, curr_roll, prev_pitch, prev_roll;
float cam_h, diff_roll, diff_pitch, OFx_trans, OFy_trans;
-// Lateral Velocity Computation
-float Velx, Vely;
-
-/** height above ground level, from ABI
- * Used for scale computation, negative value means invalid.
- */
-volatile float estimator_agl;
-
-/** default sonar/agl to use in opticflow visual_estimator */
-#ifndef OPTICFLOW_AGL_ID
-#define OPTICFLOW_AGL_ID ABI_BROADCAST
-#endif
-abi_event agl_ev;
-static void agl_cb(uint8_t sender_id, const float *distance);
-static void agl_cb(uint8_t sender_id __attribute__((unused)), const float *distance)
-{
- if (*distance > 0) {
- estimator_agl = *distance;
- }
-}
// Called by plugin
-void opticflow_plugin_init(unsigned int w, unsigned int h)
+void opticflow_plugin_init(unsigned int w, unsigned int h, struct CVresults *results)
{
// Initialize variables
imgWidth = w;
@@ -136,16 +108,17 @@ void opticflow_plugin_init(unsigned int w, unsigned int h)
curr_roll = 0.0;
OFx_trans = 0.0;
OFy_trans = 0.0;
- Velx = 0.0;
- Vely = 0.0;
+ results->Velx = 0.0;
+ results->Vely = 0.0;
+ results->flow_count = 0;
- // get AGL from sonar via ABI
- estimator_agl = -1.0;
- AbiBindMsgAGL(OPTICFLOW_AGL_ID, &agl_ev, agl_cb);
+ framerate_init();
}
-void opticflow_plugin_run(unsigned char *frame)
+void opticflow_plugin_run(unsigned char *frame, struct PPRZinfo* info, struct CVresults *results)
{
+ framerate_run();
+
if (old_img_init == 1) {
memcpy(prev_frame, frame, imgHeight * imgWidth * 2);
CvtYUYV2Gray(prev_gray_frame, prev_frame, imgWidth, imgHeight);
@@ -213,7 +186,7 @@ void opticflow_plugin_run(unsigned char *frame)
error_opticflow = opticFlowLK(gray_frame, prev_gray_frame, x, y, count_fil, imgWidth,
imgHeight, new_x, new_y, status, 5, 100);
- flow_count = count_fil;
+ results->flow_count = count_fil;
for (int i = count_fil - 1; i >= 0; i--) {
remove_point = 1;
@@ -223,13 +196,13 @@ void opticflow_plugin_run(unsigned char *frame)
}
if (remove_point) {
- for (c = i; c < flow_count - 1; c++) {
+ for (c = i; c < results->flow_count - 1; c++) {
x[c] = x[c + 1];
y[c] = y[c + 1];
new_x[c] = new_x[c + 1];
new_y[c] = new_y[c + 1];
}
- flow_count--;
+ results->flow_count--;
}
}
@@ -237,27 +210,26 @@ void opticflow_plugin_run(unsigned char *frame)
dy_sum = 0.0;
// Optical Flow Computation
- for (int i = 0; i < flow_count; i++) {
+ for (int i = 0; i < results->flow_count; i++) {
dx[i] = new_x[i] - x[i];
dy[i] = new_y[i] - y[i];
}
// Median Filter
- if (flow_count) {
- quick_sort_int(dx, flow_count); // 11
- quick_sort_int(dy, flow_count); // 11
+ if (results->flow_count) {
+ quick_sort_int(dx, results->flow_count); // 11
+ quick_sort_int(dy, results->flow_count); // 11
- dx_sum = (float) dx[flow_count / 2];
- dy_sum = (float) dy[flow_count / 2];
+ dx_sum = (float) dx[results->flow_count / 2];
+ dy_sum = (float) dy[results->flow_count / 2];
} else {
dx_sum = 0.0;
dy_sum = 0.0;
}
// Flow Derotation
- // !!WARNING!! Accessing of the state interface is NOT tread safe!!!
- curr_pitch = stateGetNedToBodyEulers_f()->theta;
- curr_roll = stateGetNedToBodyEulers_f()->phi;
+ curr_pitch = info->theta;
+ curr_roll = info->phi;
diff_pitch = (curr_pitch - prev_pitch) * imgHeight / FOV_H;
diff_roll = (curr_roll - prev_roll) * imgWidth / FOV_W;
@@ -266,7 +238,7 @@ void opticflow_plugin_run(unsigned char *frame)
prev_roll = curr_roll;
#ifdef FLOW_DEROTATION
- if (flow_count) {
+ if (results->flow_count) {
OFx_trans = dx_sum - diff_roll;
OFy_trans = dy_sum - diff_pitch;
@@ -284,22 +256,22 @@ void opticflow_plugin_run(unsigned char *frame)
#endif
// Average Filter
- OFfilter(&OFx, &OFy, OFx_trans, OFy_trans, flow_count, 1);
+ OFfilter(&OFx, &OFy, OFx_trans, OFy_trans, results->flow_count, 1);
// Velocity Computation
- if (estimator_agl < 0) {
+ if (info->agl < 0) {
cam_h = 1;
}
else {
- cam_h = estimator_agl;
+ cam_h = info->agl;
}
- if (flow_count) {
- Velx = OFy * cam_h * FPS / Fy_ARdrone + 0.05;
- Vely = -OFx * cam_h * FPS / Fx_ARdrone - 0.1;
+ if (results->flow_count) {
+ results->Velx = OFy * cam_h * FPS / Fy_ARdrone + 0.05;
+ results->Vely = -OFx * cam_h * FPS / Fx_ARdrone - 0.1;
} else {
- Velx = 0.0;
- Vely = 0.0;
+ results->Velx = 0.0;
+ results->Vely = 0.0;
}
// *************************************************************************************
diff --git a/sw/airborne/modules/computer_vision/opticflow/visual_estimator.h b/sw/airborne/modules/computer_vision/opticflow/visual_estimator.h
index a5fce5296e4..5fef180b6d7 100644
--- a/sw/airborne/modules/computer_vision/opticflow/visual_estimator.h
+++ b/sw/airborne/modules/computer_vision/opticflow/visual_estimator.h
@@ -28,16 +28,15 @@
#ifndef VISUAL_ESTIMATOR_H
#define VISUAL_ESTIMATOR_H
-// Variables used by the controller
-extern float Velx, Vely;
-extern int flow_count;
+
+#include "inter_thread_data.h"
/**
* Initialize visual estimator.
* @param w image width
* @param h image height
*/
-void opticflow_plugin_init(unsigned int w, unsigned int h);
-void opticflow_plugin_run(unsigned char *frame);
+void opticflow_plugin_init(unsigned int w, unsigned int h, struct CVresults *results);
+void opticflow_plugin_run(unsigned char *frame, struct PPRZinfo* info, struct CVresults* results);
#endif /* VISUAL_ESTIMATOR_H */
diff --git a/sw/airborne/modules/computer_vision/opticflow_module.c b/sw/airborne/modules/computer_vision/opticflow_module.c
index 247409ce7df..e47810b308a 100644
--- a/sw/airborne/modules/computer_vision/opticflow_module.c
+++ b/sw/airborne/modules/computer_vision/opticflow_module.c
@@ -28,200 +28,101 @@
#include "opticflow_module.h"
+// Computervision Runs in a thread
+#include "opticflow/opticflow_thread.h"
+#include "opticflow/inter_thread_data.h"
+
// Navigate Based On Vision, needed to call init/run_hover_stabilization_onvision
#include "opticflow/hover_stabilization.h"
// Threaded computer vision
#include
-// Frame Rate (FPS)
-#include
-
// Sockets
#include
#include
#include
#include
-#define USEC_PER_SEC 1000000L
-
-float FPS;
-
+int cv_sockets[2];
-struct CVresults {
- int x;
-};
+// Paparazzi Data
+#include "state.h"
+#include "subsystems/abi.h"
+// Downlink
+#include "subsystems/datalink/downlink.h"
-int cv_sockets[2];
+struct PPRZinfo opticflow_module_data;
-// local variables
-volatile long timestamp;
-struct timeval start_time;
-struct timeval end_time;
+/** height above ground level, from ABI
+ * Used for scale computation, negative value means invalid.
+ */
+/** default sonar/agl to use in opticflow visual_estimator */
+#ifndef OPTICFLOW_AGL_ID
+#define OPTICFLOW_AGL_ID ABI_BROADCAST
+#endif
+abi_event agl_ev;
+static void agl_cb(uint8_t sender_id, const float *distance);
-static long time_elapsed(struct timeval *t1, struct timeval *t2)
+static void agl_cb(uint8_t sender_id __attribute__((unused)), const float *distance)
{
- long sec, usec;
- sec = t2->tv_sec - t1->tv_sec;
- usec = t2->tv_usec - t1->tv_usec;
- if (usec < 0) {
- --sec;
- usec = usec + USEC_PER_SEC;
+ if (*distance > 0) {
+ opticflow_module_data.agl = *distance;
}
- return sec * USEC_PER_SEC + usec;
-}
-
-static void start_timer(void)
-{
- gettimeofday(&start_time, NULL);
-}
-
-static long end_timer(void)
-{
- gettimeofday(&end_time, NULL);
- return time_elapsed(&start_time, &end_time);
}
void opticflow_module_init(void)
{
- // Immediately start the vision thread when the module initialized
- opticflow_module_start();
+ // get AGL from sonar via ABI
+ AbiBindMsgAGL(OPTICFLOW_AGL_ID, &agl_ev, agl_cb);
+
+ // Initialize local data
+ opticflow_module_data.cnt = 0;
+ opticflow_module_data.phi = 0;
+ opticflow_module_data.theta = 0;
+ opticflow_module_data.agl = 0;
// Stabilization Code Initialization
init_hover_stabilization_onvision();
-
- // Frame Rate Initialization
- FPS = 0.0;
- timestamp = 0;
- start_timer();
}
-volatile uint8_t computervision_thread_has_results = 0;
-
void opticflow_module_run(void)
{
- // Read Latest Vision Module Results
- if (computervision_thread_has_results) {
- struct CVresults res;
- if (read(cv_sockets[0], &res, sizeof(res))) {
- perror("Failed to read CV results from socket.\n");
- }
- /* TODO: use results */
- printf("result x=%i", res.x);
-
- computervision_thread_has_results = 0;
- run_hover_stabilization_onvision();
- }
-}
-
-
-/////////////////////////////////////////////////////////////////////////
-// COMPUTER VISION THREAD
-
-// Video
-#include "v4l/video.h"
-#include "resize.h"
-
-// Payload Code
-#include "opticflow/visual_estimator.h"
-
-// Downlink Video
-//#define DOWNLINK_VIDEO 1
-
-#ifdef DOWNLINK_VIDEO
-#include "encoding/jpeg.h"
-#include "encoding/rtp.h"
-#endif
-
-#include
-
-pthread_t computervision_thread;
-volatile uint8_t computervision_thread_status = 0;
-volatile uint8_t computer_vision_thread_command = 0;
-void *computervision_thread_main(void *args);
-void *computervision_thread_main(void *args)
-{
- int socket = *(int *) args;
-
- // Video Input
- struct vid_struct vid;
- vid.device = (char *)"/dev/video2"; // video1 = front camera; video2 = bottom camera
- vid.w = 320;
- vid.h = 240;
- vid.n_buffers = 4;
-
- if (video_init(&vid) < 0) {
- printf("Error initialising video\n");
- computervision_thread_status = -1;
- return 0;
+ // Send Updated data to thread
+ opticflow_module_data.cnt++;
+ opticflow_module_data.phi = stateGetNedToBodyEulers_f()->phi;
+ opticflow_module_data.theta = stateGetNedToBodyEulers_f()->theta;
+ int bytes_written = write(cv_sockets[0], &opticflow_module_data, sizeof(opticflow_module_data));
+ if (bytes_written != sizeof(opticflow_module_data)){
+ perror("module failed to write to socket.\n");
}
- // Video Grabbing
- struct img_struct *img_new = video_create_image(&vid);
-
-#ifdef DOWNLINK_VIDEO
- // Video Compression
- uint8_t *jpegbuf = (uint8_t *)malloc(vid.h * vid.w * 2);
-
- // Network Transmit
- struct UdpSocket *vsock;
- //#define FMS_UNICAST 0
- //#define FMS_BROADCAST 1
- vsock = udp_socket("192.168.1.255", 5000, 5001, FMS_BROADCAST);
-#endif
-
- // First Apply Settings before init
- opticflow_plugin_init(vid.w, vid.h);
-
- while (computer_vision_thread_command > 0) {
- video_grab_image(&vid, img_new);
-
- // FPS
- timestamp = end_timer();
- FPS = (float) 1000000 / (float)timestamp;
- // printf("dt = %d, FPS = %f\n",timestamp, FPS);
- start_timer();
-
- // Run Image Processing
- opticflow_plugin_run(img_new->buf);
-
- /* send results to main */
- struct CVresults data;
- /* TODO: fill in results here */
- data.x = 42;
- if (write(socket, &data, sizeof(data))) {
- printf("failed to write to socket.\n");
+ // Read Latest Vision Module Results
+ struct CVresults vision_results;
+ int bytes_read = read(cv_sockets[0], &vision_results, sizeof(vision_results));
+ if (bytes_read <= sizeof(vision_results)) {
+ if (bytes_read != 0) {
+ printf("Failed to read CV results from socket.\n");
}
-
-#ifdef DOWNLINK_VIDEO
- // JPEG encode the image:
- uint32_t quality_factor = 10; //20 if no resize,
- uint8_t dri_header = 0;
- uint32_t image_format = FOUR_TWO_TWO; // format (in jpeg.h)
- uint8_t *end = encode_image(small.buf, jpegbuf, quality_factor, image_format, small.w, small.h, dri_header);
- uint32_t size = end - (jpegbuf);
-
- printf("Sending an image ...%u\n", size);
- uint32_t delta_t_per_frame = 0; // 0 = use drone clock
- send_rtp_frame(vsock, jpegbuf, size, small.w, small.h, 0, quality_factor, dri_header, delta_t_per_frame);
-#endif
- computervision_thread_has_results++;
+ } else {
+ ////////////////////////////////////////////
+ // Module-Side Code
+ ////////////////////////////////////////////
+ run_hover_stabilization_onvision(&vision_results);
}
- printf("Thread Closed\n");
- video_close(&vid);
- computervision_thread_status = -100;
- return 0;
}
void opticflow_module_start(void)
{
- /* create socket pair for communication */
+ pthread_t computervision_thread;
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, cv_sockets) == 0) {
- computer_vision_thread_command = 1;
+ ////////////////////////////////////////////
+ // Thread-Side Code
+ ////////////////////////////////////////////
int rc = pthread_create(&computervision_thread, NULL, computervision_thread_main,
&cv_sockets[1]);
if (rc) {
@@ -235,5 +136,5 @@ void opticflow_module_start(void)
void opticflow_module_stop(void)
{
- computer_vision_thread_command = 0;
+ computervision_thread_request_exit();
}