Raspberry PI 3 + OpenCV + Arduino UNO + ......(поледнее решение и вопрос в последнем сообщении)

Тема в разделе "Флудилка", создана пользователем Igor68, 21 ноя 2016.

  1. Igor68

    Igor68 Гуру

    Тема не закрыта и не забыта мною... Пока в затруднении... и в материальном тоже.
    Не выбрал ...структор для монтажа 4-х малин в один корпус и дачик-дальномер не приобрёл. С протоколом тоже неувязочка... формирую и пробую.
    Пример:
    А. Имеем одну малину с камерой, приводами и сервами через ардуину.
    Б. малину соединённую по сети с первой
    В. линукс машину (ПК)
    Г. контроллер на базе линукс.
    Б, В, Г. подключены к первой малине в качестве клиентов. Первая малина организует сеть для всего остального и является сервером для передачи изображения тем, кто требует этого. Так же по последовательному порту она управляет состоянием вышеупомянутых приводов через ардуину (надо туда ещё дальномер). По всей вероятности на неё задач уже много
    1. Малина 2(Б.) подключившись клиентом к малине 1 принимает картинку и формирует контуры из неё.
    2. Линукс машина (В.) подключившись к первой малине получает картинку из неё и делая запрос для второй малины получает картинку контуров от второй малины через первую. При приёме ответных данных линукс машина определяет что за данные и от кого они пришли. Команды управления формируются тоже на этой линукс машине и посылаются контроллеру на базе линукс. От него же она получает "карту пространства" и состояние приводов.
    3. Контроллер на базе линукс подключившись к малине 1 получает данные от неё (должен) в виде положения камеры с дальномером (на одном креплении) "строит карту пространства" и ориентируясь по ней при получении команд от линукс машины(ПК) производит управление приводами через малину 1 и ардуину.
    Контроллер на базе линукс (UC-7112-Lx-Plus) временно применён в этой схеме... пока не будет реализована "батарея" из малин.
    Соответственно вопросы про изделия - корпуса (рассматривалось в начале темы)... но может есть какие другие решения.
    Протокол обмена - единая "шапка" TCP пакета для разного типа данных.
    Протокол обмена - расширение "шапки" TCP пакета для конкретных данных.
    Совсем не понятно описание "карты пространства". Возможно уже существует (да ещё с сопоставлением видеоданных) , а я велосипед изобретаю. Ну не простая же схема представления трёхмерного пространства в виде соответствующего массива?
    Не понятна форма сохранения "карты пространства" ну... допустим в базе данных. И каким это образом лучше реализовать

    Заранее Спасибо!
    С глубоким уважением!
     
  2. Igor68

    Igor68 Гуру

    Прошу подсказки и/или совета.
    При подборе элементов столкнулся с:
    NanoPi2 нано Pi Cortex-A9 S5P4418 Bluetooth WIFI развитию

    Описание:

    Nanopi 2 посвящен Сети Дизайн Высокая производительность аппаратной платформы разработки, Использовать архитектура Cortex-A9 четырехъядерный процессор S5P4418 процессор (Частота 1.4 ГГц), памяти 1 г DDR3, Также в интегрированная 802.11b/g/n беспроводной локальной сети и 4.0 модуль, поддержка две системы Android и Debian, Поддержка HDMI и ЖК-выход синхронизации, И имеет богатый интерфейс расширения, Совместимость с малиновый пирог GPIO, Размер печатной платы только 40*75 мм.

    Ресурс характеристики:

    Процессор: S5P4418, Рабочая частота 1.4 ГГц

    Оперативная память: 1 ГБ DDR3

    Интегрированная SDIO WiFi Bluetooth модуль

    USB 2.0 типа x1

    Последовательного порта отладки x1

    Слот MicroSD X2

    MicroUSB x1: поддерживает питания и передачи данных, может быть смоделированы как последовательный порт и Ethernet

    Жк-интерфейс: 0.5 мм патч интервал fpc, Поддержка полноцветный ЖК-дисплей (rgb: 8-8-8)

    Hdmi: встретиться 1.4A спецификация, тип-разъем, 1080P60 выход

    DVP интерфейс камеры: 0.5 мм интервал вертикальной патч FPC блока, содержит МСЭ-R BT 601/656 бит, I2C и IO

    Gpio1: 2.54 мм интервал, 40pin, совместимый с rpi's gpio, uart, spi, i2c, io, и др.

    Кнопка: ключом пользователя, кнопка сброса

    СИД: индикатор питания, пользователь LED

    Размер печатной платы: 75x40 мм
    Питание: 5 В/2A постоянного тока
    Поддержка программного обеспечения: Android, Debian


    Сразу вопрос:
    - В чём подвох?
    - Насколько всё сказанное соответствует действительности и есть ли у кого опыт эксплуатации данного устройства. И если есть то какие нюансы.

    По ссылке:
    https://ru.aliexpress.com/item/Nano...lt&btsid=da24dee3-3369-4569-8fc4-7800bba7ec08
    и
    http://www.averagemanvsraspberrypi.com/2015/11/nanopi-2.html

    Сам очень доволен RPi3 но... размер для реализации задуманного и... цена! То что надо.
    - Каков разогрев?
    - Указанно 5V/2A - это не показатель, если к нему подключены ещё и какие-нибудь устройства?


    Остановился на нём в основном из-за размера и количество разъёмов минимальное. Легче будет реализовать ранее упомянутый кластер.

    Подскажите пожалуйста! Надо делать заказ!
    С глубоким уважением!
     
    Последнее редактирование: 6 янв 2017
  3. ИгорьК

    ИгорьК Гуру

    Диковинное железо...
     
  4. Igor68

    Igor68 Гуру

    Что не стоит внимания?
     
  5. ИгорьК

    ИгорьК Гуру

    Ну почему. Очень даже. Просто мало кто с ним работал здесь.
     
  6. Igor68

    Igor68 Гуру

    Вот и думаю... заказать 4 штучки... а если ещё и отличные без казусов (перегрев и т.п.) то 5 шт. Один в замен первой RPi3 по соображению габаритов... хотя нет... на подвижной части надо 2 USB интерфейса: Камера и Serial for Arduino.
     
  7. ИгорьК

    ИгорьК Гуру

    Я так и не понял глубокой сути: не проще ли на мини ПК это заделать?
     
  8. Igor68

    Igor68 Гуру

    Простите - поясните высказывание: не проще ли на мини ПК это заделать?
    Без приколов, правда не понял!
     
    Последнее редактирование: 6 янв 2017
  9. ИгорьК

    ИгорьК Гуру

    http://www.oldi.ru/catalog/element/0360300/
     
  10. Igor68

    Igor68 Гуру

    Нет это не то! У меня и так все программы только многопоточные. Даже "размазываю" их выполнение на несколько устройств, соединенных по сети. Указанное вами устройство нравится очень - сам хотел подобный купить - не хочу таскать ноутбук на работу и с работы. А Флешка для меня не выход. Таскаю малину 3 в корпусе - и к оборудованию соединяю (обычно шлюз WIFI) для связи. К сожалению пока не могу на малине делать(компилировать и отлаживать) проекты для других устройств(платформ). Почему одной малины не хватает - OpenCV прожорлив а надо хоть мало мальски в реальном времени. А Производительность архитектуры ARM ну уж больше если не считать с плавающей запятой и т.п. Да и нравится мне эта ARM архитектура (уж что-то x86 и его развитие мне не по душе) а теперь ещё и ARM64 в лице Raspberry 3. Правда Nano Pi2 это Cortex A9 конечно для меня привычный ARM32-Cortex, когда с ARM64 совсем не знаком. Так что распараллелить задачу на несколько автономных систем это в каком-то смысле и цель и решение проблемы. Это не сложно ведь! Кропотливо - вот это точно!!!!! Не понятно только выбрать само решение задачи... возвращаться назад и выбирать другой вариант накладно! Потому то и сообща правильнее! Да и все в курсе что и за чем!
     
  11. Alex19

    Alex19 Гуру

    День добрый.
    С отгремевшими праздниками!
    Рад, что у Вас дела идут, сам к выходным вернусь к своему хобби.

    Странно, может чего-то не понимаю, не специалист в данном вопросе. В сети не мало примеров OpenCV + Raspberry Pi в реальном времени. К примеру интересные проекты на Raspberry + OpenCV -

    ,

    , код к ним прилагается. Есть еще один, увы без кода

    .

    UPD. Вообще одноплатников вагон и маленькая тележка, к примеру ODROID, делает интересные платы, хотя не все дешевые. Тот же Orange Pi, Banana Pi и много других, возможно найдется тот который подходит.
     
    Последнее редактирование: 8 янв 2017
    Igor68 нравится это.
  12. Igor68

    Igor68 Гуру

    Доброго времени суток! С Отгремевшими Праздниками! Где-то мне встречались подобные примеры... какие-то даже с кодом. Кластер на базе RPi я собирался реализовать с самого начала... даже ранее самого этого проекта. Потому и выбрал схему с одним подвижным элементом этого кластера и остальными неподвижными (стационарными). Подвижную часть никак не доведу до ума... по части завершения конструкции. Для стационарной части как раз и задал вопрос по Nano Pi 2(на Али около 2000 руб)... а именно по опыту эксплуатации. Буду делать заказ на свой страх и риск на 4 штуки... и за одно датчик-дальномер (MB1232). Все 4 Nano Pi 2 по WIFI должны быть подключены к подвижному RPi 3. Далее делать проект дальше.
     
    Последнее редактирование: 9 янв 2017
  13. Igor68

    Igor68 Гуру

    Потихоньку пилю пакетный файл формирования Makefile (пробный для разных случаев):
    Код (Bash):
    #!/bin/bash

    date="09.01.2017"
    vers="01.01"
    echo ""
    echo "----- configuration project($vers) $date ------"

    omake="work/Makefile"
    ih="src/*.h"
    ic="src/*.c"
    icpp="src/*.cpp"
    oh="work"
    oc="work"
    ocpp="work"
    p1=$1


    function _help()
    {
    echo ""
    echo "--help    - current screen info"
    echo ""
    echo "-ic       - interactive config"
    echo ""
    }

    #interactive config
    function _ic()
    {
      cp $ih $oh
      cp $ic $oc
      cp $icpp $ocpp
      # Шаблон
      echo "############################################" > $omake
      echo "# Makefile Version: $vers   Date: $date" >> $omake
      echo "############################################" >> $omake
      echo "" >> $omake
      echo "#compilators" >> $omake
      echo "CPP        := g++" >> $omake
      echo "CC        := gcc" >> $omake
      echo "#" >> $omake
      echo "CFLAGS          := -c -Wall" >> $omake
      # Запросы
      echo "interactive config:"
      echo "Name Project:"
      read p1
      echo "NAME        := $p1" >> $omake
      echo "Using OpenCV:(1/0)"
      read p1
      if(($p1 > 0))
       then
        echo "INCL        := -I/usr/local/include/opencv" >> $omake
        echo "LIB        := -L/usr/local/lib" >> $omake
        echo "CPPLIBRARIES    := -lopencv_core -lopencv_imgproc -lopencv_highgui -lpthread" >> $omake
       else
        echo "INCL        :=" >> $omake
        echo "LIB        :=" >> $omake
        echo "CPPLIBRARIES    := -lpthread" >> $omake
      fi
      #Правила
      echo "SRC        := \$(shell ls *.cpp)" >> $omake
      echo "OBJ        := \$(SRC: .cpp=.o)" >> $omake
      echo "all:    \$(NAME)" >> $omake
      echo "" >> $omake
      echo "\$(NAME):    \$(OBJ)" >> $omake
      echo "    \$(CPP) \$(LIB) \$(CPPLIBRARIES) \$(OBJ) -o \$(NAME)" >> $omake
      echo "" >> $omake
      echo "\$(OBJ):    \$(SRC)" >> $omake
      echo "    \$(CPP) -c \$(SRC)" >> $omake
      echo "" >> $omake
      echo "clean:" >> $omake
      echo "    rm -f *.o \$(NAME)" >> $omake
    }


    case $p1 in
      -ic)
       _ic
       ;;
      --help)
       _help
       ;;
      *)
       echo "help for info"
       ;;
    esac
     
    Не везде будет OpenCV... да и набор функций разный. Тестовый вариант. Общая задумка:
    - Формировать Makefile
    - Копировать только необходимые файлы для компиляции (пока не сделано)
    - Формировать конфигурационный заголовочный файл config.h (пока не сделано)
    - и другое
     
    Последнее редактирование: 10 янв 2017
  14. Igor68

    Igor68 Гуру

    Вот модифицированный отрывок кода сервера:
    Код (C++):
    //поток работы с входящим соединением
    void * ServerProcess(void * cs)
    {
        int        countlive    = _time_life;
        //int        setcntlive;
        int        csock;
        int        idclient;
        WSERV        *css        = (WSERV*)(cs);
        pthread_t    pth;
        U8        midcl;
        U8        rxbuf[_tcp_size];    //буфер приёма
        U8        txbuf[_tcp_size];    //буфер передачи
        U32        txsz         = 0;
        U8        work;
        int        res;
        //
        #if(_mode_dbg)
            printf("---- CLIENT START ----\n");
        #endif
        //занимаем мютекс
        pthread_mutex_lock(&ServerMutex);
        //
        //countlive     = cs->setcntlive;
        //setcntlive    = cs->setcntlive;
        idclient    = css->idclient;        //взяли номер
        csock        = css->dtcp[idclient].csock;
        //midcl        = css->midcl[idclient];
        pth        = css->dtcp[idclient].pth;
        work        = css->work;
        //
        pthread_mutex_unlock(&ServerMutex);
        //
        while(work)
        {
            //чтение сокета
            txsz = 0;
            memset(&rxbuf[0], 0, _tcp_size);
            res = ReadSocket(csock, &rxbuf[0]);
            #if(_mode_dbg)
                printf("---- From CLIENT receive: %i\n", res);
            #endif
            switch(res)
            {
                case 0:    //Null
                    goto mexit;
                case -1:             //таймаут
                    goto mexit;
                case -2:             //какая-то ошибка сокета
                    goto mexit;
                case -3:             //ошибка размера пакета
                    break;
                default:             //нормально - данные приняты
                    countlive = _time_life;
                    break;
            }
            //обработка запроса
            pthread_mutex_lock(&ServerMutex);
            //проверяем по номеру идентификации
            if( ((*(U16*)(&rxbuf[_id_nin0])) == 0) ||    //по нулевому номеру то только к серверу
            ((*(U16*)(&rxbuf[_id_nin0])) == mainID.id_nin))    //моя идентификация
            {
                switch(rxbuf[_idtype])    //по типу обращения
                {
                    case _idtype_ID:    //работа с идентификацией
                        IDworkIDmain(&rxbuf[0], &txbuf[0]);
                        break;
                    default:    //тип обращения не понятен
                        break;
                }
            }
            #if(_main_id_type & _cfg_OpenCV)
                txsz = ServerCam(&rxbuf[0], &txbuf[0]);        //сервер камеры
            #endif
            txsz    = (*(U32*)(&txbuf[_tcp_sz0]));
            pthread_mutex_unlock(&ServerMutex);
            #if(_mode_dbg)
                printf("---- SIZE To CLIENT send: %i\n", txsz);
            #endif
            //передача данных
            if(txsz > 0)
            {
                //pthread_mutex_unlock(&ServerMutex);
                res = WriteSocket(csock, &txbuf[0], txsz);
                #if(_mode_dbg)
                    printf("---- To CLIENT send: %i\n", res);
                #endif
                switch(res)
                {
                    case 0:
                        goto mexit;
                    case -1:        //таймаут
                        goto mexit;
                    case -2:        //какая-то ошибка сокета
                        goto mexit;
                    default:        //нормально - данные переданы
                        //countlive = _time_life;
                        //printf("--send: %i\n", res);
                        break;
                }
            }
            //ожидание и новый цикл
            usleep(_cl_pr_ssleep);
            countlive--;
            if(!(countlive > 0)) //никому это соединение не нужно
                break;
        }
    mexit:    close(csock);
        pthread_mutex_lock(&ServerMutex);
        css->dtcp[idclient].pth    = 0;
        css->midcl[idclient]    = 0;
        css->cntclient--;
        pthread_mutex_unlock(&ServerMutex);
        #if(_mode_dbg)
            printf("---- CLIENT STOP ----\n");
        #endif
        pthread_exit(0);
    }
    Одним словом маленькие изменения позволили производить соединения, разъединения и повторные соединения без "замираний"

    Сейчас процесс проработки протокола и "механизмов автоконфигурации" компонентов сборки(кластера) по идентификаторам сервера и клиента. Бяд определений:
    Код (C++):
    /*
    ********************
    * для всех пакетов *
    ********************
    */

    //заголовок пакета - распределение адресов
    //размер данных - описание из 4-х байт
    #define _tcp_sz0        0x0000          //младший байт размера
    #define _tcp_sz1        0x0001          //
    #define _tcp_sz2        0x0002          //
    #define _tcp_sz3        0x0003          //
    //идентификатор типа входящего 2 байта
    #define _id_tin0        0x0004        //идентификатор типа
    #define _id_tin1        0x0005
    //идентификатор номера входящего 2 байта
    #define _id_nin0        0x0006
    #define _id_nin1        0x0007              
    //идентификатор типа исходящего 2 байта
    #define _id_tout0        0x0008        //идентификатор типа
    #define _id_tout1        0x0009
    //идентификатор номера исходящего 2 байта
    #define _id_nout0        0x000A
    #define _id_nout1        0x000B
    //общие определения для идентификаторов  
    #define _idtype            0x000C          //тип обращения - выбор режима для выбранного идентификатора -
    #define _cop            0x000D          //код операции для идентификатора
    //идентификатор времени
    #define _mtime0            0x000E
    #define _mtime1            0x000F
    //начало данных - формат для идентификаторов свой
    #define _daddr            0x0010          //начало данных
    /*определение для _idtype*/
    #define _idtype_ID        0x01        //параметр идентификации      
    //команда для _vcop - собственно код операции
    #define    _cop_rd            0x01        //чтение (от сервера клиенту) - в случае с картинкой байтовый массив картинки
    #define _cop_wr            0x02        //запись (от клиента серверу) - в случае с картинкой параметры
    #define _cop_rdwr        0x03        //чтение-запись
    #define _cop_answer        0x04        //ответ на код операции

    /*
    ************************
    * дополнение шпки для  *
    * работы с идентиф.    *
    ************************
    */

    //распределение адресов
    #define _idtypecmd        _daddr            //код операции с типом идентификатора
    #define _idcnt            (_daddr + 0x0001)    //количество описателей идентификаторов
    #define _iddat            (_daddr + 0x0002)    //данные идентификаторов
    //определения
    #define _idtypecmd_reads    0x01            //чтение идентификации сервера
    #define _idtypecmd_readc    0x02            //чтение идентификации клиента
    /*
    ***********************
    * ТИПОВЫЕ ОПРЕДЕЛЕНИЯ *
    * ИДЕНТИФИКАЦИИ       *
    ***********************
    */

    #define _cfg_server        0x0001        //сервер
    #define _cfg_sens        0x0002        //датчики
    #define _cfg_mcntrl        0x0004        //управление устройствами
    #define _cfg_video        0x0005        //видеоданные
    #define _cfg_space        0x0010        //пространство, положение
    #define _cfg_neuro        0x0020        //нейроматрица
    #define _cfg_move_cam        0x0040        //поворот камеры
    #define _cfg_OpenCV        0x0080        //применение OpenCV
    #define _cfg_motors        0x0100        //управление моторами

    //структура идентификации
    typedef struct _DID
    {
        u_int16_t        id_tin;        //тип идентификатора входящего
        u_int16_t        id_nin;        //номер идентификатора входящего
        u_int16_t        id_tout;    //тип идентификатора исходящего
        u_int16_t        id_nout;    //номер идентификатора исходящего
    } DID;

    /*
    ************************
    * дополнение шапки     *
    * для камеры           *
    ************************
    */

    //распределение адресов
    #define _vtype            _daddr                //тип видеоданных
    #define _vlayer            (_daddr + 0x0001)        //слой отображения - номер
    #define _vwidht                 (_daddr + 0x0002)        //ширина в случае работы с картинкой
    #define _vheight                (_daddr + 0x0004)        //высота в случае работы с картинкой
    #define    _ap1            (_daddr + 0x0006)        //параметр 1 для адаптивной бинаризации
    #define    _ap2            (_daddr + 0x0007)        //параметр 2 для адаптивной баниризации
    #define _vdaddr                 (_daddr + 0x0010)              //начало данных картинки
    Всё это позволит сконфигурировать комплекс автоматически... даже если в разной последовательности производить включение элементов "системы"
    snapshot26.png snapshot27.png
    Компоненты должны автономно сконфигурироваться самостоятельно. Делается общий пакет на всё... включая возможность применения и в QtCreator
    Потому только для возможности задавать вопрос и приводятся отрывки. Сейчас делается автоопределение идентификации по номеру... тип (функциональность) задаётся по файлу конфигурации и пакетному файлу bash.
     
    Последнее редактирование: 12 янв 2017
    Alex19 нравится это.
  15. Igor68

    Igor68 Гуру

    Задача: Автоидентификация...
    Общий смысл.
    1) Запускается сервер, который имеет:
    - Типовую идентификацию(пост выше), определённую в конфигурации (фактически это функциональные возможности)... при компиляции
    #define _cfg_server 0x0001 //сервер
    #define _cfg_sens 0x0002 //датчики
    #define _cfg_mcntrl 0x0004 //управление устройствами
    #define _cfg_video 0x0005 //видеоданные
    #define _cfg_space 0x0010 //пространство, положение
    #define _cfg_neuro 0x0020 //нейроматрица
    #define _cfg_move_cam 0x0040 //поворот камеры
    #define _cfg_OpenCV 0x0080 //применение OpenCV
    #define _cfg_motors 0x0100 //управление моторами

    - Идентификационный номер тоже по конфигурации.
    Из сказанного ясны возможности и назначения.
    2) Запускается один из клиентов, который по аналогичным определениям имеет и функциональное назначение и идентификационный номер.
    При подключении клиента к серверу и обмене сервер сверяет совпадения номера идентификации со своим или уже подключенными номерами других клиентов. В случае совпадения номера сервер в своём ответе клиенту вместо запрошенных данных передаёт команду изменения номера вместе с новым номером. клиент приняв вместо ответа команду исполняет её.
    3) Клиент у сервера опрашивает в цикле список функциональностей у сервера для всех возможностей (функций), необходимых для своей работы
    4) Клиент обращается к ресурсам всех элементов системы в своём цикле по номеру идентификации
    5) - Если запрос по номеру идентификации принадлежит серверу - он выполняет команду и выдаёт ответ с данными запросившему клиенту
    - Если запрос по номеру идентификации принадлежит другому клиенту - то он передаёт этот запрос соответствующему клиенту и по обратному "пути" возвращает ответ
    По смыслу: Зарос в своем составе имеет номера: кому и от кого согласно номерам идентификации для каждого. Ответ имеет аналогичные параметры номерной идентификации.
    Клиент аналогично серверу имеет возможность вместо ответа выдавать запрос

    Собственно вопрос:
    Необходимо более корректное описание функциональности!

    Например конечная точка (сервер) имеет свойства выдачи картинки, которую могут запросить клинт1 и клиент2. Клиент1 требует её для отображения. Кроме этого клиент1 требует тоже картинку от клиента2, но уже в "контурном" описании. Клиент1 наложит контуры (слой 1) на картинку (слой 0).
    Возможен "смысловой конфликт" в понимании "видеоданные"

    Может есть соображения?
    Тестирование пока выявило отсутствие "тормозов" в новой схеме - при распределении по назначениям для разных элементов.

    Заранее спасибо!
    С Глубоким Уважением! Со Старым Новым Годом!!!
     
  16. Igor68

    Igor68 Гуру

    ...Ещё одна моя тупость... ну может не совсем тупость но:
    Для упрощения типов переменных я сделал некоторый заголовочный файл types.h (один только фрагмент):
    Код (C++):
    #ifndef BYTE
    #define BYTE unsigned char
    #endif
    #ifndef uchar
    #define uchar unsigned char
    #endif
    #ifndef uint8
    #define uint8 uchar
    #endif
    #ifndef u8
    #define u8 uchar
    #endif
    #ifndef U8
    #define U8 uchar
    #endif
     
    Но где-то применены определения которым наплевать на #ifndef а если точнее typedef, которому наплевать что тип уже определён через #define, как правило это в стандартных определениях через #include <sys/types.h> к примеру. Так вот "упрощение" для себя типа "U8" и/или "BYTE" ну или подобное часто чревато... и подобные "упрощения" это лишний геморрой для себя если применяемые библиотеки (типа OpenCV) которые используют стандартные определения.
    Учтите это касается не только GCC, но и других компиляторов.... Будьте внимательны с описанием типов данных!!!!!!!!!!!!!!!!!!!!
    Потому как будет возникать много вполне не нужных вопросов и не только на этом форуме!
    Спасибо!
     
    Последнее редактирование: 14 янв 2017
    Alex19 и ИгорьК нравится это.
  17. ИгорьК

    ИгорьК Гуру

    Можно поинтересоваться, для чего Вы это делаете? Обычно, попытка ввода типового определения вызывает у IDE неприодолимое желание дописать его самостоятельно.
     
  18. Igor68

    Igor68 Гуру

    Доброго времени суток!
    Когда-то что-то попадались такие типы как WORD, DWORD и ещё множество всяких... в основном при применении чужого кода (фрагментов). Ну и сделал для себя заголовочный файл types.h в котором и описал ряд типов... точнее не описал, а определил

    #ifndef BYTE
    #define BYTE unsigned char
    #endif

    ну и так далее. Удобно стало вроде ни тебе unsigned short а U16 или даже u16 никаких телодвижений в написании кода... набрал буковку и размер в битах и всё. Ан нет... где-то (в каком-то заголовочном файле) всё же попадётся типа typedef где никаких упоминаний о будущих #define которые сначала кто-то проверяет через #ifndef (а вдруг это уже кто-то делал) перед определением... обратите внимание что это всегда в заголовочном файле применяется для устранения двойных определений... но с typedef не прокатывает.
    Сам маялся недавно... вроде всё нормально - а не компилится гад:mad:. В OpenCV где-то прикрутили что-то через typedef - потом нашел. Выяснил по своей уонфигурации :
    Код (C++):
    //config.h

    #ifndef _config_h_
    #define _config_h_

    //#include "types.h"
    #include "tdef.h"

    /*
    ****************
    * конфигурация *
    ****************
    */

    /* задаём - указываем */
    // == сообщения для отладки ==
    //определяет, что в консоли вудут выводиться сообщения
    #define _mode_dbg            1
    // == мы клиент ==
    //мы кодключаемся к серверу в начале работы
    #define _mode_client            0
    // == номер идентификации ==
    //наш номер идентификации по умолчанию (Номер)
    #define _main_id_num            1
    // == функциональное назначение ==
    //камера OpenCV
    #define _func_cam            0
    //поворот камеры
    #define _func_cam_move            1


    /* по заданию */
    // == мы сервер ==
    #if(_mode_client == 0)
        #define _mode_server        1    //сервер
    #else
        #define _mode_server        0    //клиент
    #endif
    // == тип идентификации ==
    //видеокамера
    #if(_func_cam)
        #define _mitc            (_cfg_sens | _cfg_video | _cfg_OpenCV)
    #else
        #define _mitc            0
    #endif
    //перемещение видеокамеры и управление приводами
    #if(_func_cam_move)
        #define _mitcm            (_cfg_mcntrl | _cfg_move_cam)
    #endif
    //наш идентификатор типа
    #define _main_id_type            (_mitc | _mitcm | _mode_server)

    //количество моторов движения
    #define _motors_cnt            4
    //количество сервомашин
    #define _servos_cnt            18

    #endif
     
    Одним словом код делаю в "куче" на всё - стоит только через 1 и 0 указать что будет для компиляции. В самом коде соответственно:
    Код (C++):
    #if(_main_id_type & _cfg_OpenCV)
        #include <iostream>
        #include <opencv2/imgproc/imgproc.hpp>
        #include <opencv2/imgproc/imgproc_c.h>
        #include <opencv2/highgui/highgui.hpp>
    #endif
    ...........
    ..........
    ..........
    #if(_main_id_type & _cfg_OpenCV)
        cv::Mat gray;
        cv::Mat adapt;
        cv::Mat ga;
        //параметры для процедур
        u_int8_t    ap1;
        u_int8_t    ap2;
    #endif
    ..................
    ..................
    ..................
    #if(_main_id_type & _cfg_OpenCV)
    //информация о параметрах камеры
    int vinfo(void)
    {
        capture = cvCreateCameraCapture(0);
        if(!(capture))
            return 1;
        width = (int)(cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH));
            height = (int)(cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT));
        //
        cvReleaseCapture(&capture);
        return 0;
    }
    #endif
    Ну и так далее... выгодно видите ли. Но вот при разной конфигурации вышло, что где-то уже определён BYTE и на проверку типа #ifndef BYTE ноль эмоций... и возникают двойные определения. Ведь typedef после себя оставляет только тип и... никаких следов для препроцессора, который после проверки (вроде как проверки) где-то вновь скажет что
    unsigned char это одно и то же что и BYTE
    Для того и предыдущее моё сообщение
     
    ИгорьК нравится это.
  19. ZAZ-965

    ZAZ-965 Гуру

    Igor68, а если свой код обернуть в namespace?
     
  20. Igor68

    Igor68 Гуру

    Да нет... не можно в моём случае определять таким образом. Пользуюсь редактором nano, gedit и компилятором gcc/g++ по причине отсутствия опыта организации "пространства"... да и список файлов (cpp;h) зависит от конфигурации и не только cjnfig.h, но и config.sh.
    И ещё (вот этим выгребаю пиксели из массива OpenCV):
    Код (C++):
    while(cnty < height)
        {
            cntx = 0;
            while(cntx < width)
            {
                switch(vtype)
                {
                    case _vtype_scr8:    //картинка
                        (*(u_int8_t*)(ob + cntbyte)) = gray.at<char>(cnty,cntx);
                        break;
                    case _vtype_scr_at:    //адаптивная бинаризация
                        (*(u_int8_t*)(ob + cntbyte)) = adapt.at<char>(cnty,cntx);
                        break;
                    case _vtype_scr_ap:    //картинка И адаптивная бинаразация
                        (*(u_int8_t*)(ob + cntbyte)) = ga.at<char>(cnty,cntx);
                        break;
                    default:
                        break;
                }
                cntx++;
                cntbyte++;
            }
            cnty++;
        }
    Проде всё нормально - собираю в одномерный массив для передачи клиенту. Делал и в вдухмерном массиве buf[x][y] а в клиенте что-то переставлено (другая среда разработки) и картинка - хлам! Потому и делаю несколько "лишних" преобразований и в сервере и в клиенте
    в клиенте, согласно вышеприведённому листингу:
    Код (C++):
    y     = 0;
        cnt    = 0;
        while(y < height)
        {
            x = 0;
            while(x < width)
            {
                switch(layer)
                {
                    case 0:
                        vbuf[x][y] = (*(u_int8_t*)(rbuf + _vdaddr + cnt));
                        break;
                    case 1:
                        vbuf1[x][y] = (*(u_int8_t*)(rbuf + _vdaddr + cnt));
                        break;
                    case 2:
                        vbuf2[x][y] = (*(u_int8_t*)(rbuf + _vdaddr + cnt));
                        break;
                    case 3:
                        vbuf3[x][y] = (*(u_int8_t*)(rbuf + _vdaddr + cnt));
                        break;
                    default:
                        #if(_mode_dbg)
                            printf("RD CAM ANSWER not layer\n");
                        #endif
                        break;
                }
                cnt++;
                x++;
            }
            y++;
        }
    Понял, что в принципе одно и тоже для разных компиляторов - разное. Имею ввиду многомерные массивы.

    Но в пределах одного компилятора всё нормально и спокойно с помощью memcpy(&buf[0][0], &buf2[0][0], sizeof(buf2))
     
    Последнее редактирование: 15 янв 2017