puku0x / cvdrone

CV Drone (= OpenCV + AR.Drone)
https://github.com/puku0x/cvdrone/wiki/How-to-build
Other
203 stars 93 forks source link

Can you build a linux version? #2

Closed heyeast closed 10 years ago

heyeast commented 11 years ago

hi. It is a great project. The code is simple but powerful. Now, I want to use it in Linux and I tried to migrate it to Linux. but there are some problems before me .

The biggest one is how to migrate the pthread code to the linux, like this:

// Thread for navdata int flagNavdata; HANDLE threadNavdata, mutexNavdata; UINT loopNavdata(void); static UINT WINAPI runNavdata(void _args) { return reinterpretcast<ARDrone>(args)->loopNavdata(); }

I am not familiar with pthread coding. I tried to change it with linux pthread function. but there is a "Segmentation fault" in running. I think it is caused by pthread. But I can not find the bug.

Thank you for your consideration and I will be looking forward to your reply.

puku0x commented 11 years ago

Hi heyeast,

I changed creating threads from _beginthreadex() to pthread_create() in the latest commit. It will help you.

Thanks, puku0x

heyeast commented 11 years ago

Hi puku0x It works for me. I really appreciate it. Thank u very much!

heyeast

puku0x commented 11 years ago

Sorry to keep you all waiting ! CV Drone supports Linux now !!

Sincerely, puku0x

hamid-q commented 10 years ago

hi puku0x

I'm running ubuntu cvdrone in and after a few minutes or less, the program is run out of a "segmentation fault" appears at the terminals.

Please help me.Thanks

puku0x commented 10 years ago

Hi hamid-q,

Thank you for your report.

Unfortunately, I didn't face that bug when I run it in ubuntu 12.04 LTS.

Are you using the latest AR.Drone firmware and CV Drone ? What kind of code did you run ? CV Drone's sample or your original one ?

Thank you, puku0x

hamid-q commented 10 years ago

Thanks for the answers puku0x.

i connect to ardrone and type in browser ftp://192.168.1.1:5551/version.text , and Saw '2.4.8'. also i download CV Drone of this link : 'https://github.com/puku0x/cvdrone'. after make(no sample,i wont run original main), i run ./test, and after few seconds Closing program and see this "Segmentation fault (core dumped)" in terminal. also using ubuntu 12.04LTS. Thank you for help

puku0x commented 10 years ago

Hi hamid-q,

Oh, I didn't test with 2.4.8 yet. May be the size of NAVDATA struct is changed or a new CONFIG data is added in the latest firmware.

I'll check it soon !

Regards, puku0x

hamid-q commented 10 years ago

hi puku0x thanks for your attention, Do you think possible it's a problem of the OS?

Sincerely hamid

puku0x commented 10 years ago

Hi hamid,

I updated AR.Drone's firmware to 2.4.8 and ran the latest CV Drone on Ubuntu 12.04 LTS on the Virtual Box.

Unfortunately, I couldn't see the same error. Hmm..., I don't know whether it was a problem of the OS or not, but it may be a solution trying it on other OS (or updating dependent libraries by apt-get).

Thanks, puku0x

hamid-q commented 10 years ago

hi Ppuku0x dear i tested CVdrone one another laptop(OS: ubuntu 12.04 LTS) and good worked. i using of opencv function for example((cv::findContours(image, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); andcv::inRange(imgHSV, cv::Scalar(104,108,1), cv::Scalar(130,240,124), imgThresh) )) but run time show this error (OpenCV Error: Assertion failed (k == STD_VECTOR_MAT) in getMat, file /build/buildd/opencv-2.3.1/modules/core/src/matrix.cpp, line 918 terminate called after throwing an instance of 'cv::Exception' what(): /build/buildd/opencv-2.3.1/modules/core/src/matrix.cpp:918: error: (-215) k == STD_VECTOR_MAT in function getMat

Aborted (core dumped) )into terminal,Do you have a solution?

realy thanKs

Sincerely Hamid

puku0x commented 10 years ago

Hi Hamid,

Could you send your code to me ? It is very difficult to advise without knowing how you used the functions.

Regards, puku0x

hamid-q commented 10 years ago

hi Puku0xth This is program, and this functions are problem : cv::findContours(image, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); , cv::inRange(imgHSV, cv::Scalar(104,108,1), cv::Scalar(130,240,124), imgThresh);.

/////////////////

include "ardrone/ardrone.h"

include

include

// -------------------------------------------------------------------------- // main(Number of arguments, Argument values) // Description : This is the entry point of the program. // Return value : SUCCESS:0 ERROR:-1 // -------------------------------------------------------------------------- /using namespace cv; using namespace std;/ //window detection double angle( cv::Point, cv::Point, cv::Point ); void find_squares(cv::Mat&, std::vectorstd::vector&); cv::Mat colordetection(cv::Mat);//IplImage ); //This function threshold the HSV image and create a binary image cv::Mat GetThresholdedImage(cv::Mat imgHSV){ //rad : cvInRangeS(imgHSV, cvScalar(170,160,60), cvScalar(180,256,256), imgThresh); cv::Mat imgThresh; imgThresh.create(imgHSV.rows,imgHSV.cols,CV_32F); // assert(imgHSV==CV_8UC3); //inRange(imgHSV, Scalar(104,178,70), Scalar(130,240,124), imgThresh); cv::inRange(imgHSV, cv::Scalar(104,108,1), cv::Scalar(130,240,124), imgThresh); return imgThresh; } ///////////////////////////////////////////// int main(int argc, char *_argv) { // AR.Drone class ARDrone ardrone;

// Initialize
if (!ardrone.open()) {
    printf("Failed to initialize.\n");
    return -1;
}

// Battery
printf("Battery = %d%%\n", ardrone.getBatteryPercentage());

// Instructions
printf("***************************************\n");
printf("*       CV Drone sample program       *\n");
printf("*           - How to Play -           *\n");
printf("***************************************\n");
printf("*                                     *\n");
printf("* - Controls -                        *\n");
printf("*    'Space' -- Takeoff/Landing       *\n");
printf("*    'Up'    -- Move forward          *\n");
printf("*    'Down'  -- Move backward         *\n");
printf("*    'Left'  -- Turn left             *\n");
printf("*    'Right' -- Turn right            *\n");
printf("*    'Q'     -- Move upward           *\n");
printf("*    'A'     -- Move downward         *\n");
printf("*                                     *\n");
printf("* - Others -                          *\n");
printf("*    'C'     -- Change camera         *\n");
printf("*    'Esc'   -- Exit                  *\n");
printf("*                                     *\n");
printf("***************************************\n\n");

while (1) {
    // Key input
    int key = cvWaitKey(33);
    if (key == 0x1b) break;

    // Update
    if (!ardrone.update()) break;

    // Get an image
    //IplImage *image = ardrone.getImage();
cv::Mat image= ardrone.getImage();
///////////window detect//////////////////
    cv::Mat image1;
image.copyTo(image1);
     image1=color_detection(image1);

        // Detect all regions in the image that are similar to a rectangle

    std::vector<std::vector<cv::Point> > squares;
    find_squares(image1, squares);
    ////////end window detect/////////////////
    // Take off / Landing 
    if (key == ' ') {
        if (ardrone.onGround()) ardrone.takeoff();
        else                    ardrone.landing();
    }

    // Move
    double vx = 0.0, vy = 0.0, vz = 0.0, vr = 0.0;
    if (key == 'w') vx =  1.0;
    if (key == 's') vx = -1.0;
if (key == 'a') vy =  1.0;
if (key == 'd') vy = -1.0;
    if (key == 'q') vr =  1.0;
if (key == 'e') vr = -1.0;
    if (key == 'z') vz =  1.0;
    if (key == 'x') vz = -1.0;
    ardrone.move3D(vx, vy, vz, vr);

    // Change camera
    static int mode = 0;
    if (key == 'c') ardrone.setCamera(++mode%4);

cv::imshow("camera", image);
}

// See you
ardrone.close();

return 0;

}

//***** cv::Mat color_detection(cv::Mat frame)//IplImage *image) { // cvNamedWindow("Blue");

        frame=frame.clone();// cvCloneImage(frame);
        cv::medianBlur(frame,frame,9);
        cv::Mat imgHSV ;//= cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3);
        imgHSV.create(frame.rows,frame.cols,CV_32F);
       cvtColor(frame,frame,CV_BGR2HSV);
       cv::Mat imgThresh= GetThresholdedImage(frame);     
           return frame;//imgThresh;

}

void find_squares(cv::Mat& image, std::vectorstd::vector& squares) { std::vectorstd::vector contours;

// find squares in every color plane of the image
for (int c = 0; c < 3; c++)
{
    int ch[] = {c, 0};
    //mixChannels(&blurred, 1, &gray0, 1, ch, 1);

    // try several threshold levels
    const int threshold_level = 2;
    for (int l = 0; l < threshold_level; l++)
    {
        cv::findContours(image, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
        //CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE
        // Test contours
        std::vector<cv::Point> approx;

        for (size_t i = 0; i < contours.size(); i++)
        {
            // approximate contour with accuracy proportional
            // to the contour perimeter
        //    cout<<i<<endl;

            //contours.resize(contours.size()+1);
            approxPolyDP(cv::Mat(contours[i]), approx, arcLength(cv::Mat(contours[i]), true)*0.02, true);
    ///     approxPolyDP(Mat(contours.at(i)), approx, arcLength(Mat(contours.at(i)), true)*0.02, true);
            // Note: absolute value of an area is used because
            // area may be positive or negative - in accordance with the
            // contour orientation
            if (approx.size() == 4 &&
                fabs(contourArea(cv::Mat(approx))) > 1000 &&
                isContourConvex(cv::Mat(approx)))
            {
                double maxCosine = 0;

                for (int j = 2; j < 5; j++)
                {
                    //approx.resize(j+10);
                    double cosine =fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
                    maxCosine = MAX(maxCosine, cosine);
                }
                if (maxCosine < 0.3)
                {
                            squares.push_back(approx);
                }
            }
        }
    }
}

}

////////////////////// double angle( cv::Point pt1, cv::Point pt2, cv::Point pt0 ) { double dx1 = pt1.x - pt0.x; double dy1 = pt1.y - pt0.y; double dx2 = pt2.x - pt0.x; double dy2 = pt2.y - pt0.y; return (dx1_dx2 + dy1_dy2)/sqrt((dx1_dx1 + dy1dy1)(dx2_dx2 + dy2*dy2) + 1e-10); }

puku0x commented 10 years ago

Hi Hamid,

I found you input a multi-channel (CV_8U3C) image to cv::findContours(). The function accepts only single-channel (CV_8U1C) image.

You should ask this question in OpenCV forum because here is where to report a bug in CV Drone.

#include "ardrone/ardrone.h"

// OpenCV
#include <opencv2/opencv.hpp>
#include <math.h>
#include <vector>

// --------------------------------------------------------------------------
// main(Number of arguments, Argument values)
// Description : This is the entry point of the program.
// Return value : SUCCESS:0 ERROR:-1
// --------------------------------------------------------------------------
int main(int argc, char *argv)
{
    // AR.Drone class
    ARDrone ardrone;

    // Initialize
    if (!ardrone.open()) {
        printf("Failed to initialize.\n");
        return -1;
    }

    // Battery
    printf("Battery = %d%%\n", ardrone.getBatteryPercentage());

    while (1) {
        // Key input
        int key = cvWaitKey(33);
        if (key == 0x1b) break;

        // Update
        if (!ardrone.update()) break;

        // Get an image
        cv::Mat image = ardrone.getImage();

        // Grayscale
        cv::Mat edge;
        cv::cvtColor(image, edge, CV_BGR2GRAY);

        // Blur
        const int k = 3;
        cv::blur(edge, edge, cv::Size(k, k));

        // Canny edge
        cv::Canny(edge, edge, 150, 255);
        cv::imshow("edge", edge);

        // Find coutours
        std::vector<std::vector<cv::Point>> contours;
        cv::findContours(edge, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);     // CV_RETR_LIST or CV_RETR_EXTERNAL

        // Find rectangle
        // http://stackoverflow.com/questions/8667818/opencv-c-obj-c-detecting-a-sheet-of-paper-square-detection
        std::vector<std::vector<cv::Point>> squares;
        for (size_t i = 0; i < contours.size(); i++) {
            // Approximate
            std::vector<cv::Point> approx;
            cv::approxPolyDP(cv::Mat(contours[i]), approx, cv::arcLength(cv::Mat(contours[i]), true)*0.02, true);

            // It seems a rectangle
            if (approx.size() == 4) {
                // Add a rectangle
                squares.push_back(approx);
            }
        }

        // Show rectangle(s)
        for (size_t i = 0; i < squares.size(); i++) {
            for (size_t j = 0; j < squares[i].size(); j++) {
                cv::line(image, (squares[i])[j], (squares[i])[(j+1)%4], cv::Scalar(0,255,0));
            }
        }

        // Take off / Landing 
        if (key == ' ') {
            if (ardrone.onGround()) ardrone.takeoff();
            else                    ardrone.landing();
        }

        // Move
        double vx = 0.0, vy = 0.0, vz = 0.0, vr = 0.0;
        if (key == 'w') vx =  1.0;
        if (key == 's') vx = -1.0;
        if (key == 'a') vy =  1.0;
        if (key == 'd') vy = -1.0;
        if (key == 'q') vr =  1.0;
        if (key == 'e') vr = -1.0;
        if (key == 'z') vz =  1.0;
        if (key == 'x') vz = -1.0;
        ardrone.move3D(vx, vy, vz, vr);

        // Change camera
        static int mode = 0;
        if (key == 'c') ardrone.setCamera(++mode%4);

        cv::imshow("camera", image);
    }

    // See you
    ardrone.close();

    return 0;
}

Thank you, puku0x

hamid-q commented 10 years ago

hi puku0x Thank you for help.

Sincerely hamid