Примечание: внизу страницы добавлена контактная информация, она также присутствует и на главной страничке сайта
Wild Baby ver 0.3
Создан контроллер для робота.
Основные характеристики контроллера:
Помимо контроллера обновлено програмное обеспечение. Описание версии Ядра Удаленного Контроля смотрите ниже (тамже где и описание предыдущих версий). Нужно сказать, что по неизвестным причинам происходят сбои при работе с BlueTooth на платформе Windows Mobile 2003 (на КПК ipac 2210). Я очень долго пытался найти ошибку, и вот выяснил, что сбой происходит при простом чтении/записи в порт (без использования многопоточности и принудительной остановки операции ввода/вывода). Возможно сбаивает радио модуль робота, но тогда сбой был бы замечен и на ПК, но этого не просходит. Но что-то конкретное пока сказать на этот счет сложно.
Wild Baby ver 0.2
О самой первой версии робота (Версия 0.1, 2004 - 2005 гг.)
Физические характеристики
Создана основная плата для робота. Плата имеет следующие характеристики:
Плата устанавливается на четырехколесной платформе. Эта платформа имеет два двигателя (двигатель тяги и двигатель рулевой машинки) и два датчика освещенности.
Програмное обеспечение
Разработан предварительный протокол обмена данных между удаленной частью (дистанционно управляемая машина - ДУМ) и ПК. На ДУМ была реализована базовая система команд. Была создна приметивная программа на ПК, которая демонстрировала возможности протокола и существующей системы команд ДУМ.
Версия 0.2
После того, как была написана первая тестовая программа для работы с роботом, стало понятно, что необходимо ввести такое понятие как "команда". Тоесть в процедурах работы с роботом, разумеется надо абстрагироваться от физических особенностей канала связи. Еще захотелось сделать так, чтобы один поток работы с роботом блокировал не всю функциональность канала, а только то, что ему нужно. Тоесть чтобы поток, который только отсылает данные роботу не блокировал возможность чтения данных из робота. Ведь робот может состоять из разных паралельно работающих частей, которые имеют один канал связи. И еще система ДУМ-ПК - это система реального времени. Это значит, что нужно, чтобы команды занимали ресурс не больше чем для них отведено. Я решил, что нужно сделать нечто вроде ядра, которое моглобы принимать запросы программы с ПК и в порядке очереди (очередей) их исполнять. И вот, что получилось.
И еще... И еще просто хотелось набраться практического опыта в создании систем реального времени :-) Это интересно!
Ядро удаленного контроля (версия 0.9.0) (текущая версия)
Добавлена система протоколирования
OTracer - класс, который использует для протоколирования callback процедуру, заданную пользователем.
OHTMLTracer - класс, который генерирует html трассы.
OTracinClass - класс, унаследовавшись от которого, пользовательский класс сможет использовать удобные методы для составления самых подробных трасс работы объекта. Это, в первую очередь, методы EnterMethod(methodname) и LeaveMethod(methodname), с помощью которых в отчет заносится информация о том, что произошел вызов метода и о том, что работа метода завершена соответственно. Для составления отчетов к этому классу можно подключать, как OTracer, так и OHTMLTracer.
Исправлены баги
Метод ProcessCommand объекта CCommandSender. В этом методе сейчас используется процедура ORealTimeProc, поскольку после выхода из метода ORealTimeProc::ShutDown можно быть уверенным, что поток больше не существует, и все операции ввода-вывода, выполнявшиеся в потоке завершены.
ORealTimeProc. Иногда в случае тайаута возможны были аварийные сбои, это связано было с тем, что поток не усыплялся перед уничтожением.
Ядро удаленного контроля (версия 0.8.0)
Добавлено исключение OException. Класс содержит метод GetInfo, который возвращает указатель на строку, описывающую ошибку и ее место. Исключение бросается в пределах Real Time API и CCommandRemoteKernel. Пока оно одно на все случаи жизни.
Исправлены некоторые ошибки. В основном это ошибки связанные с неверным порядком уничтожения потоков. В доработанной версии планируется уменьшить количество принудительных остановок потоков.
В силу того, что компиляторы разных сред воспринимают код по-разному, средо-зависимые участки кода расписаны для каждой среды. Сам тип среды объявляется в файле CpDfns.h, он задается с помощью #define. Сейчас поддерживается два типа среды: Visual Studio .NET 2003 и eMbedded Visual C++ SP3. Для первой среды надо объявить RTAPI_VS71, а для второй RTAPI_EVC4SP3.
В Real Time API появились методы GetMachineTime и Sleep. К тому же следуюет отметить что события OEvent сами сбрасываеются после того, как их фиксирует первый из ождающих методов типа WaitFor.
Ядро удаленного контроля (версия 0.7.1)
Новшества версии 0.7.1 (относительно версии 0.6.2)
Реализован Real Time API, который теперь полностью заменяет Win API. В соответствии с этим немного поменялось содержание классов библиотеки. Например благодаря возможности переиспользования потоков, минимальное время нужное для выполнения команды уменьшилось почти в 20 раз. Раньше возможно было выполнять около 3000 пустых команд в секунду, теперь это число возросло до 50 000 (с хвостиком :-) ). Эксперименты на произовдительность библиотеки проводолись на машине со след характеристиками:
AMD Duron 750 МГц, 256 RAM, Win XP Professional.
Изменения затрунулись и пользовательской части. Все ожидающие константы WaitResult, перенесены - теперь это rtapi::OAwaiter::ENMWaitResult (rtapi::OAwaiter::WR_TIMEOUT). Еще перенесены константы, характеризующие результат работы, теперь обращение к ним такое: rtapi::ENMThreadResult (rtapi::TR_OK например).
Интерфейс библиотеки
В целом суть этой библиотеки заключается в том, что с помощью нее можно достаточно легко реализовать множество сетевых протоколов. В первую очередь это касается нестандартных протоколов, для которых еще не созданно так называемых классов-оболочек.
Идея здесь следующая. В библиотеке доминируют два понятия: команда и ядро (признаюсь, что термина нормального пока еще не придумал). Команда - это объект, в котором определены, действия, которые надо выполнить удаленному устройству. Тут пользователю библиотеки нужно определить порядок операций ввода/вывода, или использовать уже готовую команду со стандартным поведением. Ядро - это то, что призвано исполнять команды пользователя. Пользователь помещает команды в специальные внутренние очереди ядра. Ядро, по большому счету играет здесь роль буфера - оно извелкает команды из очереди и приводит их в исполнение.
Типы команд
В всех определенных ниже классах обязательно присутствует метод DirectProcess. Это виртуальный метод, вызываемый ядром для исполнения команды. Для всех команд можно настроить таймаут. Для CDefaultCommand можно сконфигурировать входные и выходные параметры. Чтобы использовать классы приведенные ниже, пользователю нужно переопределить метод DirectProcess. В CDefaultCommand этого делать не надо - ведь там уже все сделано. В этом классе команд опредены действия команды, которые выполняются "по умолчанию". Мало того - я бы вообще не хотел, чтобы этот класс использовался как родительский. Очень жалко, что в стандартном С++ нельзя запретить наследование.
Каждая команда позволяет внутри метода DirectProcess вызывать другие команды (минуя размещение в ядре). Здесь налагаются ограничения по правам. Команды предназначенные только для чтения могут либо читать из канала связи (CInFunctionality::ReceiveData), либо вызывать другие "читающие" команды (ProcInCmd). Аналогичная ситуация с командами, предназначенными исключительно для записи. Что же какасается команд ввода/вывода - их две.
Все классы команд, кроме CDefaultCommand - являются абстрактными. Для использования их возможностей от них необходимо унаследовать свои классы с переопределенным методом DirectProcess.
Очень внимательно надо относиться к указанию таймаутов - по умолчанию там установлен бесконечный таймаут.
Все классы являются потомками CBaseCommand. И именно в нем объявлен DirectProcess. Это очень важно. Этот метод имеет единственнй параметр - ссылку на класс-оболочку вокруг канала связи.
И еще важно знать, что все классы наследют какую-либо функциональность: либо функциональность вывода (COutFunctionality), либо функциональность ввода (CInFunctionality), либо и ту и ту.
Канал связи
От канала связи требуется совсем немного. Отсылать поток байтов, и принимать поток байтов. Поэтому внутри ядра и команды доступны максимум два метода связанные напрямую с этим объектом:
Для этого канала определено три интерфейса
Если нужно приспособить какой-либо канал связи - реализуйте в нем интерфейс ICommProtected. Этот интерфейс является совокупностью интерфесов ICommI и ICommO.
Сейчас интерфейс ICommProtected реализует класс CComm, являющийся оболочкой вокруг последовательного порта. Работает он просто. Основная часть параметров настравается по умолчанию и при хорошем исходе для его запуска достаточно двух строк:
CComm comm("COM1", 9600);
comm.OpenComm();
А завершение работы с портом выглядит так:
comm.CloseComm();
Методы ядра
Ядро - это объект, который нужно перед началом работы запускать, а после - останавливать. Еще очень важной его функциональнстью является возможность исполнять команды, которые в него помещает пользователь.
Подключение библиотеки
Библиотека протестирована и работает на платформах Windows XP и Windows Mobile 2003.
Объявление классов библиотеки находится в файле RemoteCommandKernel.h
Библиотека требует, чтобы в проект была включена библиотека MFC.
Для того чтобы библиотека компилировалась в среде eMbedded Visual Studio 4.0 SP3 (eVC) также требуется, чтобы в проект была включена библиотека MFC, плюс - в директиве #include желательно добавить к именам файлов стандартных библиотек расширение ".h". Раньше у меня эта студия ругалась на отсутствия этой буковки. Но в последнее время она сильно изменилась, и перестала ругаться.
Несколько слов по поводу реализации STL. STL для eVC от Microsoft - реализовано с багом (ошибка линковки при включении map.h). Я пользовался библиотеками от Silicon Graphics/HP: http://www.syncdata.it/stlce/index.html
Помимо этого, для того, чтобы компиляция прошла успешно, нужно включить в проект файлы CommandRemoteKernel.h, CommandRemoteKernel.cpp, Comm.h, Comm.cpp и Rdfns.h.
И еще. В классе CComm реализована возможность создания потока для отслеживания событий порта. Не используйте эту возможность в Windows Mobile 2003. Есть подозрение, что функция WaitCommEvent в этой ОС работает некорректно (а эта функция там очень важна). Начать надо с того, что эта ОС не поддерживает OVERLAPPED структуры. Мои же подозрения заключяются вот в чем. Допустим вы проверяете RX буфер порта (ClearCommError) и он пуст, разумно было бы вызвать WaitCommEvent для ожидания байта. Но если байт приходит между проверкой буфера и вызовом WaitCommEvent, то об этом узнать невозможно, WaitCommEvent не учитывает этот случай и ожидает следующий байт - тоесть вы теряете байт, это очень часто является причиной неудачной операции ввода\вывода. WaitCommEvent в этой версии MS Windows не дает гарантии, что я не пропущу ни одного байта.
Получение библиотеки
Библиотека является свободным програмным обеспечением. Подробнее об этом написано в начале ее каждого исходного файла (включен неофициальный русский перевод).
Архив с исходным кодом библиотеки версии 0.9.0 (текущая версия) находится здесь.
Архив с исходным кодом библиотеки версии 0.8.0 (текущая версия) находится здесь.
Архив с исходным кодом библиотеки версии 0.7.1 находится здесь.
Архив с исходным кодом библиотеки версии 0.6.2 находится здесь.
Архив с исходным кодом библиотеки версии 0.6.1 находится здесь.
Архив с кодом версии 0.5.1 находится здесь
Лицензия GNU GPL расположена здесь.
Проект "Wild Baby PLS", Сентябрь 2006
Почта: StpWorld@narod.ru