Параллельное выполнение
function test(name)
{
echo(name + ": 1");
echo(name + ": 2");
echo(name + ": 3");
} |;
// параллельное выполнение
test("left") & test ("right");
[00000000] *** left: 1
[00000000] *** right: 1
[00000000] *** left: 2
[00000000] *** right: 2
[00000000] *** left: 3
[00000000] *** right: 3
Разница между параллельным и последовательным выполнением двух действий состоит в том, что при параллельном выполнении операция делится на отдельные инструкции и очередь состоит из чередующихся инструкций первого и второго вызовов функции test
![Фотография](https://vse.kz/public/style_images/osnovnoi34/profile/default_large.png)
Программирование на квадрокоптере AR.Drone
Автор erbol, 07.03.2013, 17:42
#42
Отправлено 01.04.2013, 20:18:55
![](https://vse.kz/public/style_images/osnovnoi34/post_offline.png)
Оператор "," запускает группу команд в фоновом режиме.
=> {echo(1); echo(2); echo(3); echo(4); echo(5); } , {echo(6); echo(7); echo(8 ); echo(9); echo(10); } ,
{echo(11); echo(12); echo(13); echo(14); echo(15); } , {echo(16); echo(17); echo(18); echo(19); echo(20); } , {echo(21); echo(22); echo(23); echo(24); echo(25); } ;
#[0031850925] *** 1
#[0031850926] *** 6
#[0031850926] *** 2
#[0031850926] *** 11
#[0031850926] *** 7
#[0031850926] *** 3
#[0031850926] *** 16
#[0031850926] *** 12
#[0031850926] *** 8
#[0031850926] *** 4
#[0031850927] *** 21
#[0031850927] *** 17
#[0031850927] *** 13
#[0031850927] *** 9
#[0031850927] *** 5
#[0031850927] *** 22
#[0031850927] *** 18
#[0031850927] *** 14
#[0031850927] *** 10
#[0031850927] *** 23
#[0031850927] *** 19
#[0031850927] *** 15
#[0031850928] *** 24
#[0031850928] *** 20
#[0031850928] *** 25
Порядок действий : Сначала выполняется действие в группе в которой еще не выполнялись действия, затем последовательно возвращаемся назад, выполняя следующие операции в каждой предыдущей группе.
=> {echo(1); echo(2); echo(3); echo(4); echo(5); } , {echo(6); echo(7); echo(8 ); echo(9); echo(10); } ,
{echo(11); echo(12); echo(13); echo(14); echo(15); } , {echo(16); echo(17); echo(18); echo(19); echo(20); } , {echo(21); echo(22); echo(23); echo(24); echo(25); } ;
#[0031850925] *** 1
#[0031850926] *** 6
#[0031850926] *** 2
#[0031850926] *** 11
#[0031850926] *** 7
#[0031850926] *** 3
#[0031850926] *** 16
#[0031850926] *** 12
#[0031850926] *** 8
#[0031850926] *** 4
#[0031850927] *** 21
#[0031850927] *** 17
#[0031850927] *** 13
#[0031850927] *** 9
#[0031850927] *** 5
#[0031850927] *** 22
#[0031850927] *** 18
#[0031850927] *** 14
#[0031850927] *** 10
#[0031850927] *** 23
#[0031850927] *** 19
#[0031850927] *** 15
#[0031850928] *** 24
#[0031850928] *** 20
#[0031850928] *** 25
Порядок действий : Сначала выполняется действие в группе в которой еще не выполнялись действия, затем последовательно возвращаемся назад, выполняя следующие операции в каждой предыдущей группе.
Сообщение отредактировал erbol: 01.04.2013, 21:07:21
#43
Отправлено 02.04.2013, 09:59:13
![](https://vse.kz/public/style_images/osnovnoi34/post_offline.png)
BionicOpter - робот-стрекоза от FESTO
http://www.youtube.com/watch?feature=player_embedded&v=nj1yhz5io20#!
http://www.youtube.com/watch?feature=player_embedded&v=nj1yhz5io20#!
#44
Отправлено 02.04.2013, 11:00:03
![](https://vse.kz/public/style_images/osnovnoi34/post_offline.png)
Программирование на URBI
Из этого примера видно что команда sleep() не считается самостоятельной единицей процесса, а как бы выполняет роль "пробела" между операциями
{ echo("11") ; sleep(0.1s) ; echo("12") },
{ echo("21") ; sleep(6s) ; echo("22") },
#[0001063068] *** 11
#[0001063068] *** 21
#[0001063168] *** 12
#[0001069068] *** 22
Сначала быстро идет вывод первых трех значений - 11, 21, 12, а затем ждем 6 секунд появления числа 22
=> { echo("11") ; echo("12") ; echo("13") },
{ echo("21") ; echo("22"); echo("23") },
#[0001134523] *** 11
#[0001134523] *** 21
#[0001134523] *** 12
#[0001134523] *** 22
#[0001134523] *** 13
#[0001134524] *** 23
Из этого примера видно что команда sleep() не считается самостоятельной единицей процесса, а как бы выполняет роль "пробела" между операциями
{ echo("11") ; sleep(0.1s) ; echo("12") },
{ echo("21") ; sleep(6s) ; echo("22") },
#[0001063068] *** 11
#[0001063068] *** 21
#[0001063168] *** 12
#[0001069068] *** 22
Сначала быстро идет вывод первых трех значений - 11, 21, 12, а затем ждем 6 секунд появления числа 22
=> { echo("11") ; echo("12") ; echo("13") },
{ echo("21") ; echo("22"); echo("23") },
#[0001134523] *** 11
#[0001134523] *** 21
#[0001134523] *** 12
#[0001134523] *** 22
#[0001134523] *** 13
#[0001134524] *** 23
Сообщение отредактировал erbol: 02.04.2013, 11:13:32
#45
Отправлено 02.04.2013, 15:55:33
![](https://vse.kz/public/style_images/osnovnoi34/post_offline.png)
Из этих двух примеров видно как интерпретатор воспринимает команду sleep(). Именно , как интервал времени через который будет запущен на выполнение следующий за ним оператор
=> loop
{
echo("ping"); sleep(1s);
mytag: { echo("pong"); sleep(1s); };
},
sleep(1s);echo("pg");
#[0017685628] *** ping
#[0017686629] *** pg
#[0017686629] *** pong
#[0017687630] *** ping
#[0017688630] *** pong
#[0017689631] *** ping
=> loop
{
echo("ping"); sleep(1s);
mytag: { echo("pong"); sleep(1s); };
},
sleep(6s);echo("pg");
#[0017639461] *** ping
#[0017640462] *** pong
#[0017641462] *** ping
#[0017642463] *** pong
#[0017643463] *** ping
#[0017644463] *** pong
#[0017645463] *** pg
#[0017645463] *** ping
#[0017646464] *** pong
=> loop
{
echo("ping"); sleep(1s);
mytag: { echo("pong"); sleep(1s); };
},
sleep(1s);echo("pg");
#[0017685628] *** ping
#[0017686629] *** pg
#[0017686629] *** pong
#[0017687630] *** ping
#[0017688630] *** pong
#[0017689631] *** ping
=> loop
{
echo("ping"); sleep(1s);
mytag: { echo("pong"); sleep(1s); };
},
sleep(6s);echo("pg");
#[0017639461] *** ping
#[0017640462] *** pong
#[0017641462] *** ping
#[0017642463] *** pong
#[0017643463] *** ping
#[0017644463] *** pong
#[0017645463] *** pg
#[0017645463] *** ping
#[0017646464] *** pong
#46
Отправлено 02.04.2013, 16:20:28
![](https://vse.kz/public/style_images/osnovnoi34/post_offline.png)
Еще одно замечание по поводу кода который приводится в руководстве пользователя URBI
Обычно код пишут таким образом
// Теперь, печатаем сообщение когда выполняем код тега
loop
{
echo("ping"); sleep(1s);
mytag: { echo("pong"); sleep(1s); };
},
sleep(3.5s);
[00000000] *** ping
[00001000] *** pong
[00002000] *** ping
[00003000] *** pong
// блокируем вывод pong
mytag.block;
sleep(3s);
// половина кода цикла больше не выполняется
[00004000] *** ping
[00005000] *** ping
[00006000] *** ping
// разблокируем pong
mytag.unblock;
sleep(3.5s);
[00008000] *** pong
[00009000] *** ping
[00010000] *** pong
[00011000] *** ping
Мне например было непонятно какую роль выполняет команда sleep() в комбинациях
mytag.block;
sleep(3s);
и
loop
{
echo("ping"); sleep(1s);
mytag: { echo("pong"); sleep(1s); };
},
sleep(3.5s);
На самом деле приводится вывод результата в перемежку с участками кода
Код для этого примера выглядит таким образом
loop
{
echo("ping"); sleep(1s);
mytag: { echo("pong"); sleep(1s); };
},
sleep(5s);
mytag.block;
sleep(5s);
mytag.unblock;
sleep(3.5s);
Обычно код пишут таким образом
// Теперь, печатаем сообщение когда выполняем код тега
loop
{
echo("ping"); sleep(1s);
mytag: { echo("pong"); sleep(1s); };
},
sleep(3.5s);
[00000000] *** ping
[00001000] *** pong
[00002000] *** ping
[00003000] *** pong
// блокируем вывод pong
mytag.block;
sleep(3s);
// половина кода цикла больше не выполняется
[00004000] *** ping
[00005000] *** ping
[00006000] *** ping
// разблокируем pong
mytag.unblock;
sleep(3.5s);
[00008000] *** pong
[00009000] *** ping
[00010000] *** pong
[00011000] *** ping
Мне например было непонятно какую роль выполняет команда sleep() в комбинациях
mytag.block;
sleep(3s);
и
loop
{
echo("ping"); sleep(1s);
mytag: { echo("pong"); sleep(1s); };
},
sleep(3.5s);
На самом деле приводится вывод результата в перемежку с участками кода
Код для этого примера выглядит таким образом
loop
{
echo("ping"); sleep(1s);
mytag: { echo("pong"); sleep(1s); };
},
sleep(5s);
mytag.block;
sleep(5s);
mytag.unblock;
sleep(3.5s);
#47
Отправлено 03.04.2013, 14:00:29
![](https://vse.kz/public/style_images/osnovnoi34/post_offline.png)
Начинаем манипулировать роботом. Есть драйвер который может дать команду поморгать лампочками
Теперь можно в зависимости от высоты drone над поверхностью «моргать» различным образом
Высоту пока зададим с помощью оператора trajectories , а именно таким образом
var y = 0.5;
{
sleep(1.5s);
y = 4 smooth:10s,
},
every (1s) echo(y);
Тогда вывод полученный от URBI будет таким
=> var y = 0.5;
{
sleep(1.5s);
y = 4 smooth:10s,
},
every (1s) echo(y);
#[0000203689] 0.5
#[0000203690] *** 0.5
#[0000204691] *** 0.5
#[0000205691] *** 0.519898
#[0000206691] *** 0.685923
#[0000207691] *** 1.00505
#[0000208691] *** 1.44605
#[0000209690] *** 1.96558
#[0000210691] *** 2.51333
#[0000211691] *** 3.03509
#[0000212690] *** 3.47977
#[0000213690] *** 3.80433
#[0000214690] *** 3.97679
#[0000215690] *** 4
#[0000216690] *** 4
Включаем drone, подключаемся к его сети, подгружаем драйвер URBI для drone и даем команду
=> var DroneLed = DroneLed.new;
var y = 0.5;
{
sleep(1.5s);
y = 4 smooth:10s,
},
every (1s) {echo(y); }, at(y>2) { echo("led");DroneLed.led;};
#[0003161017] object_381
#[0003161017] 0.5
#[0003161018] *** 0.5
#[0003162018] *** 0.5
#[0003163018] *** 0.519898
#[0003164018] *** 0.685893
#[0003165018] *** 1.00499
#[0003166018] *** 1.44596
#[0003167018] *** 1.96577
#[0003167079] *** led
#[0003168018] *** 2.51328
#[0003169018] *** 3.03478
#[0003170018] *** 3.47992
#[0003171018] *** 3.80448
#[0003172018] *** 3.97674
#[0003173019] *** 4
#[0003174019] *** 4
#[0003175018] *** 4
drone моргает светодиодами когда Y становится больше 2
Теперь можно в зависимости от высоты drone над поверхностью «моргать» различным образом
Высоту пока зададим с помощью оператора trajectories , а именно таким образом
var y = 0.5;
{
sleep(1.5s);
y = 4 smooth:10s,
},
every (1s) echo(y);
Тогда вывод полученный от URBI будет таким
=> var y = 0.5;
{
sleep(1.5s);
y = 4 smooth:10s,
},
every (1s) echo(y);
#[0000203689] 0.5
#[0000203690] *** 0.5
#[0000204691] *** 0.5
#[0000205691] *** 0.519898
#[0000206691] *** 0.685923
#[0000207691] *** 1.00505
#[0000208691] *** 1.44605
#[0000209690] *** 1.96558
#[0000210691] *** 2.51333
#[0000211691] *** 3.03509
#[0000212690] *** 3.47977
#[0000213690] *** 3.80433
#[0000214690] *** 3.97679
#[0000215690] *** 4
#[0000216690] *** 4
Включаем drone, подключаемся к его сети, подгружаем драйвер URBI для drone и даем команду
=> var DroneLed = DroneLed.new;
var y = 0.5;
{
sleep(1.5s);
y = 4 smooth:10s,
},
every (1s) {echo(y); }, at(y>2) { echo("led");DroneLed.led;};
#[0003161017] object_381
#[0003161017] 0.5
#[0003161018] *** 0.5
#[0003162018] *** 0.5
#[0003163018] *** 0.519898
#[0003164018] *** 0.685893
#[0003165018] *** 1.00499
#[0003166018] *** 1.44596
#[0003167018] *** 1.96577
#[0003167079] *** led
#[0003168018] *** 2.51328
#[0003169018] *** 3.03478
#[0003170018] *** 3.47992
#[0003171018] *** 3.80448
#[0003172018] *** 3.97674
#[0003173019] *** 4
#[0003174019] *** 4
#[0003175018] *** 4
drone моргает светодиодами когда Y становится больше 2
#48
Отправлено 04.04.2013, 13:29:08
![](https://vse.kz/public/style_images/osnovnoi34/post_offline.png)
Код драйвера URBI к drone обновил, теперь можно указывать длительность, частоту анимации и ее вид
#include <urbi/uobject.hh> #include <stdio.h> #include <string.h> #include <winsock2.h> #include <windows.h> #define PORT 5556 #define SERVERADDR "192.168.1.1" // Виды анимаций светодиодами #define BLINK_GREEN_RED 0 #define BLINK_GREEN 1 #define BLINK_RED 2 #define BLINK_ORANGE 3 #define SNAKE_GREEN_RED 4 #define FIRE 5 #define STANDARD 6 #define RED 7 #define GREEN 8 #define RED_SNAKE 9 #define BLANK 10 #define RIGHT_MISSILE 11 #define LEFT_MISSILE 12 #define DOUBLE_MISSILE 12 #define FRONT_LEFT_GREEN_OTHERS_RED 13 #define FRONT_RIGHT_GREEN_OTHERS_RED 14 #define REAR_RIGHT_GREEN_OTHERS_RED 15 #define REAR_LEFT_GREEN_OTHERS_RED 16 #define LEFT_GREEN_RIGHT_RED 17 #define LEFT_RED_RIGHT_GREEN 18 #define BLINK_STANDARD 19 class DroneLed: public urbi::UObject { public: // The class must have a single constructor taking a string. DroneLed(const std::string& str); int init(); // Our variable. urbi::UVar v; // Our method. double add (double); int led(int var1, int var2) ; }; // the constructor defines what is available from Urbi DroneLed::DroneLed(const std::string& s) : urbi::UObject(s) // required { // Bind the variable. UBindVar (DroneLed, v); // Bind the function. UBindFunction (DroneLed, add); UBindFunction (DroneLed, led); UBindFunction(DroneLed, init); }; int DroneLed::init() { return 0; }; double DroneLed::add (double rhs) { return ((double)v + rhs); } int DroneLed::led(int var1, int var2) { //Инициализируем библиотеку WinSock с промощью вызова функции WSAStartup int my_sock; char buff[10 * 1014]; printf("UDP DEMO Client\nType quit to quit\n"); // Шаг 1 - иницилизация библиотеки Winsocks if (WSAStartup(0x202, (WSADATA *)&buff[0])) { printf("WSAStartup error: %d\n", WSAGetLastError()); return -1; } /* Создание сокета и присвоение значения дескриптору сокета для UDP пакетов * AF_INET - protocol family * SOCK_DGRAM - Raw protocol interface */ if (( my_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { printf("socket"); return -1; } // Объявляем переменные dest_addr и hst HOSTENT *hst; sockaddr_in dest_addr; dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons(PORT); // определение IP-адреса узла if (inet_addr(SERVERADDR) != INADDR_NONE) dest_addr.sin_addr.s_addr = inet_addr(SERVERADDR); else { if (hst = gethostbyname(SERVERADDR)) dest_addr.sin_addr.s_addr = ((unsigned long **) hst->h_addr_list)[0][0]; else { printf("Unknown host: %d\n", WSAGetLastError()); closesocket(my_sock); WSACleanup(); return -1; } } char buf[256]; //int id = SNAKE_GREEN_RED; int id = var1; int freq = 1073741824; //int duration = 5; int duration = var2; int seq = 1; sprintf(buf, "AT*LED=%d,%d,%d,%d\r", seq, id, freq, duration); sendto(my_sock, buf, strlen(buf)+1, 0,(sockaddr *)&dest_addr, sizeof(dest_addr)); // Шаг последний - выход closesocket(my_sock); WSACleanup(); return 0; } UStart(DroneLed);
#49
Отправлено 04.04.2013, 13:31:02
![](https://vse.kz/public/style_images/osnovnoi34/post_offline.png)
Анимацию светодиодами AR.Drone можно выполнить двумя разными способами
1. С помощью команды AT*LED
int id = SNAKE_GREEN_RED;
float freq = 0.5;
int duration = 5;
sprintf(buf, "AT*LED=%d,%d,%d,%d\r", seq++, id, *(int*)(&freq), duration);
sendto(sock, buf, strlen(buf)+1, 0, (sockaddr*)&server_addr, sizeof(sockaddr_in));
2. С помощью команды AT*CONFIG
sprintf(buf, "AT*CONFIG_IDS=%d,\"%s\",\"%s\",\"%s\"\r", seq++, ARDRONE_SESSION_ID, ARDRONE_PROFILE_ID, ARDRONE_APPLOCATION_ID);
sendto(sock, buf, strlen(buf)+1, 0, (sockaddr*)&server_addr, sizeof(sockaddr_in));
sprintf(buf, "AT*CONFIG=%d,\"leds:leds_anim\",\"%d,%d,%d\"\r", seq++, id, *(int*)(&freq), duration);
sendto(sock, buf, strlen(buf)+1, 0, (sockaddr*)&server_addr, sizeof(sockaddr_in));
https://projects.ard...opics/show/5017
1. С помощью команды AT*LED
int id = SNAKE_GREEN_RED;
float freq = 0.5;
int duration = 5;
sprintf(buf, "AT*LED=%d,%d,%d,%d\r", seq++, id, *(int*)(&freq), duration);
sendto(sock, buf, strlen(buf)+1, 0, (sockaddr*)&server_addr, sizeof(sockaddr_in));
2. С помощью команды AT*CONFIG
sprintf(buf, "AT*CONFIG_IDS=%d,\"%s\",\"%s\",\"%s\"\r", seq++, ARDRONE_SESSION_ID, ARDRONE_PROFILE_ID, ARDRONE_APPLOCATION_ID);
sendto(sock, buf, strlen(buf)+1, 0, (sockaddr*)&server_addr, sizeof(sockaddr_in));
sprintf(buf, "AT*CONFIG=%d,\"leds:leds_anim\",\"%d,%d,%d\"\r", seq++, id, *(int*)(&freq), duration);
sendto(sock, buf, strlen(buf)+1, 0, (sockaddr*)&server_addr, sizeof(sockaddr_in));
https://projects.ard...opics/show/5017
#50
Отправлено 04.04.2013, 13:31:25
![](https://vse.kz/public/style_images/osnovnoi34/post_offline.png)
Каждый способ анимации имеет свое название и номер. Можно посмотреть здесь
https://www.robotapp...e-LEDs/100.html
Можно еще посмотреть на саму анимацию в картинках
http://gauth.fr/2011...-ar-drone-leds/
https://www.robotapp...e-LEDs/100.html
Можно еще посмотреть на саму анимацию в картинках
http://gauth.fr/2011...-ar-drone-leds/
#52
Отправлено 04.04.2013, 23:30:14
![](https://vse.kz/public/style_images/osnovnoi34/post_offline.png)
Вроде бы работающий код для получения навигационных данных под linux, попробую адаптировать под Windows
https://projects.ard...50#message-5545
/* drone.c loop to awake drone : AT*CONFIG=seqnum,"general:navdata_demo","TRUE" set unicast mode on : sendto navdata_socket, &one, 4 Wed Oct 26 12:15:54 CEST 2011 rp skeleton for ardrone navdata gcc ardrone1.c -o ardrone1 -I /home/iris2/ARDrone_SDK_Version_1_8_20110726/ARDroneLib/Soft/Common/ -I /home/iris2/ARDrone_SDK_Version_1_8_20110726/ARDroneLib/VP_SDK/ -I /home/iris2/ARDrone_SDK_Version_1_8_20110726/ARDroneLib/Soft/Lib/ */ #include "navdata_common.h" #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <fcntl.h> #define NAVDATA_PORT 5554 #define AT_PORT 5556 #define NAVDATA_BUFFER_SIZE 2048 #define WIFI_MYKONOS_IP "192.168.1.1" int seq=0; char msg[NAVDATA_BUFFER_SIZE]; int at_socket = -1, //sendto navdata_socket = -1; //recvfrom struct sockaddr_in pc_addr, //INADDR_ANY drone_at, //send at addr drone_nav, //send nav addr from; void awake() { char command[256]; while(1) { if(seq<2) sprintf(command,"AT*CONFIG=%d,\"general:navdata_demo\",\"TRUE\"\r",seq); else sprintf(command,"AT*COMWDG=%d\r",seq); sendto(at_socket, command, strlen(command), 0, (struct sockaddr*)&drone_at, sizeof(drone_at) ); seq++; usleep(100000); //shoud be less than 0.5s to get all datas ? } } int main() { navdata_t *data; int l,size; int32_t one = 1,zero=0; printf("drone v1.0.2\n"); if((at_socket = socket (AF_INET, SOCK_DGRAM, 0)) < 0){ printf ("at_socket error: %s\n", strerror(errno)); goto fail; }; if((navdata_socket = socket (AF_INET, SOCK_DGRAM, 0)) < 0){ printf ("navdata_socket: %s\n", strerror(errno)); goto fail; }; //for recvfrom pc_addr.sin_family = AF_INET; pc_addr.sin_addr.s_addr = htonl(INADDR_ANY); pc_addr.sin_port = htons(NAVDATA_PORT); //for sendto AT drone_at.sin_family = AF_INET; drone_at.sin_addr.s_addr = inet_addr(WIFI_MYKONOS_IP); drone_at.sin_port = htons(AT_PORT); //for sendto navadata init drone_nav.sin_family = AF_INET; drone_nav.sin_addr.s_addr = inet_addr(WIFI_MYKONOS_IP); drone_nav.sin_port = htons(NAVDATA_PORT); if(fork()) awake(); if(bind( navdata_socket, (struct sockaddr *)&pc_addr, sizeof(pc_addr)) < 0){ printf ("bind: %s\n", strerror(errno)); goto fail; }; //set unicast mode on sendto(navdata_socket, &one, 4, 0, (struct sockaddr *)&drone_nav, sizeof(drone_nav)); while ( 1 ) { size=0; size = recvfrom ( navdata_socket, &msg[0], NAVDATA_BUFFER_SIZE, 0x0, (struct sockaddr *)&from, (socklen_t *)&l); printf("\33[2J\nread %d data ",size); for(l=0;l<size;l++) printf("%02x ",0xff & msg[l]); data=(navdata_t *)msg; printf("header %x battery %d alt %d vx %f theta %f", data->header, ((navdata_demo_t*)((data->options)))->vbat_flying_percentage, ((navdata_demo_t*)((data->options)))->altitude, ((navdata_demo_t*)((data->options)))->vx, ((navdata_demo_t*)((data->options)))->theta ); fflush(stdout); //sleep(1); } fail: return 0; }
https://projects.ard...50#message-5545
#53
Отправлено 06.04.2013, 10:25:11
![](https://vse.kz/public/style_images/osnovnoi34/post_offline.png)
Получение навигационных данных с AR.Drone
При включении робот открывает у себя несколько портов для сетевого взаимодействия с клиентом
Порт 5554 используется для инициации периодической отправки данных с сенсоров. Данные поступают на порт 5554 компьютера клиента
5556 порт робота используется для получения команд от клиента
Определенна процедура которая сообщает роботу о желании клиента получать данные сенсоров (навигационных данных). Клиент отправляет кодовое слово на порт 5556 drone.
Клиент определяет количество передаваемых данных. С помощью команды AT*CONFIG=seq, general:navdata_demo,TRUE. Команда передается на порт 5554 drone
seq это порядковый номер команды, он должен быть уникален. Существует два режима отправки данных - полный режим и демо-режим.
После инициализации отправки данных с робота клиент постоянно отсылает роботу команду AT*COMWDG=seq. Эта команда не дает роботу "заснуть". Ее надо посылать не реже 5 раз в секунду
#54
Отправлено 06.04.2013, 10:26:19
![](https://vse.kz/public/style_images/osnovnoi34/post_offline.png)
Отсылка и прием данных
http://rus-linux.net...kets-API-4.html
http://www.opennet.r...cket/node8.html
Особенностью функции recvfrom является то что она блокирует выполнение программы до тех пор пока не получит данные.
Функция имеет 6 аргументов. Первый аргумент это целое число - идентификатор сокета, мы получаем его как результат создания сокета функцией socket. Второй аргумент это указатель на символьный массив.
Результатом работы функции recvfrom как раз является содержимое этого символьного массива. Все полученные данные помещаются в него
Третий аргумент это длина символьного массива.
Четвертый аргумент флаг, В нашем случае имеет значение 0
Пятый и шестой аргументы определяют источник данных
http://rus-linux.net...kets-API-4.html
http://www.opennet.r...cket/node8.html
Особенностью функции recvfrom является то что она блокирует выполнение программы до тех пор пока не получит данные.
Функция имеет 6 аргументов. Первый аргумент это целое число - идентификатор сокета, мы получаем его как результат создания сокета функцией socket. Второй аргумент это указатель на символьный массив.
Результатом работы функции recvfrom как раз является содержимое этого символьного массива. Все полученные данные помещаются в него
Третий аргумент это длина символьного массива.
Четвертый аргумент флаг, В нашем случае имеет значение 0
Пятый и шестой аргументы определяют источник данных
#55
Отправлено 06.04.2013, 13:23:27
![](https://vse.kz/public/style_images/osnovnoi34/post_offline.png)
Текст консольной программы для управления drone
Запускаем так
DLed.exe 2 2
Первый аргумент определяет вид анимации лампочками AR.Drone, второй аргумент - длительность анимации
Виды анимации можно посмотреть по ссылке
http://gauth.fr/2011...-ar-drone-leds/
[/size] #include <stdio.h> #include <string.h> #include <winsock2.h> #include <windows.h> #define PORT 5556 #define SERVERADDR "192.168.1.1" // Виды анимаций светодиодами #define BLINK_GREEN_RED 0 #define BLINK_GREEN 1 #define BLINK_RED 2 #define BLINK_ORANGE 3 #define SNAKE_GREEN_RED 4 #define FIRE 5 #define STANDARD 6 #define RED 7 #define GREEN 8 #define RED_SNAKE 9 #define BLANK 10 #define RIGHT_MISSILE 11 #define LEFT_MISSILE 12 #define DOUBLE_MISSILE 12 #define FRONT_LEFT_GREEN_OTHERS_RED 13 #define FRONT_RIGHT_GREEN_OTHERS_RED 14 #define REAR_RIGHT_GREEN_OTHERS_RED 15 #define REAR_LEFT_GREEN_OTHERS_RED 16 #define LEFT_GREEN_RIGHT_RED 17 #define LEFT_RED_RIGHT_GREEN 18 #define BLINK_STANDARD 19 int main(int argc, char *argv[]) { if(argc!=3) { printf("You forgot to enter parameters.\n"); exit(1); } //printf("Hello %s", argv[1]); //Инициализируем библиотеку WinSock с промощью вызова функции WSAStartup int my_sock; char buff[10 * 1014]; //printf("UDP DEMO Client\nType quit to quit\n"); // Шаг 1 - иницилизация библиотеки Winsocks if (WSAStartup(0x202, (WSADATA *)&buff[0])) { printf("WSAStartup error: %d\n", WSAGetLastError()); return -1; } /* Создание сокета и присвоение значения дескриптору сокета для UDP пакетов * AF_INET - protocol family * SOCK_DGRAM - Raw protocol interface */ if (( my_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { printf("socket"); return -1; } // Объявляем переменные dest_addr и hst HOSTENT *hst; sockaddr_in dest_addr; dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons(PORT); // определение IP-адреса узла if (inet_addr(SERVERADDR) != INADDR_NONE) dest_addr.sin_addr.s_addr = inet_addr(SERVERADDR); else { if (hst = gethostbyname(SERVERADDR)) dest_addr.sin_addr.s_addr = ((unsigned long **) hst->h_addr_list)[0][0]; else { printf("Unknown host: %d\n", WSAGetLastError()); closesocket(my_sock); WSACleanup(); return -1; } } char buf[256]; //int id = SNAKE_GREEN_RED; // конвертируем строку в число int id = atol(argv[1]); int freq = 1073741824; //int duration = 5; int duration = atol(argv[2]); int seq = 1; sprintf(buf, "AT*LED=%d,%d,%d,%d\r", seq, id, freq, duration); sendto(my_sock, buf, strlen(buf)+1, 0,(sockaddr *)&dest_addr, sizeof(dest_addr)); // Шаг последний - выход printf("Hello %s", argv[1]); closesocket(my_sock); WSACleanup(); return 0; } [size=3]
В свойствах проекта Компоновщик -> Ввод -> Дополнительные зависимости пишем имя библиотеки сокетов для Windows - ws2_32.lib
#56
Отправлено 06.04.2013, 16:06:44
![](https://vse.kz/public/style_images/osnovnoi34/post_offline.png)
Текст консольной программы для получения навигационных данных от drone
В свойствах проекта Компоновщик -> Ввод -> Дополнительные зависимости пишем имя библиотеки сокетов для Windows - ws2_32.lib
Выводит периодически заряд батареи робота в процентах
В свойствах проекта Компоновщик -> Ввод -> Дополнительные зависимости пишем имя библиотеки сокетов для Windows - ws2_32.lib
Выводит периодически заряд батареи робота в процентах
#include <stdio.h> #include <string.h> #include <winsock2.h> #include <windows.h> #define NAVDATA_PORT 5554 #define AT_PORT 5556 #define NAVDATA_BUFFER_SIZE 2048 #define WIFI_MYKONOS_IP "192.168.1.1" int seq=0; char msg[NAVDATA_BUFFER_SIZE]; int at_socket = -1, //sendto navdata_socket = -1; //recvfrom struct sockaddr_in pc_addr, //INADDR_ANY drone_at, //send at addr drone_nav, //send nav addr from; int main() { int l,size; char trig[] = { 0x01, 0x00, 0x00, 0x00 }; char command[256]; //Инициализируем библиотеку WinSock с промощью вызова функции WSAStartup char buff[10 * 1014]; //printf("UDP DEMO Client\nType quit to quit\n"); // Шаг 1 - иницилизация библиотеки Winsocks if (WSAStartup(0x202, (WSADATA *)&buff[0])) { printf("WSAStartup error: %d\n", WSAGetLastError()); return -1; } if((at_socket = socket (AF_INET, SOCK_DGRAM, 0)) < 0){ printf ("at_socket error: %s\n", strerror(errno)); goto fail; }; if((navdata_socket = socket (AF_INET, SOCK_DGRAM, 0)) < 0){ printf ("navdata_socket: %s\n", strerror(errno)); goto fail; }; //for recvfrom pc_addr.sin_family = AF_INET; pc_addr.sin_addr.s_addr = htonl(INADDR_ANY); pc_addr.sin_port = htons(NAVDATA_PORT); //for sendto AT drone_at.sin_family = AF_INET; drone_at.sin_addr.s_addr = inet_addr(WIFI_MYKONOS_IP); drone_at.sin_port = htons(AT_PORT); //for sendto navadata init drone_nav.sin_family = AF_INET; drone_nav.sin_addr.s_addr = inet_addr(WIFI_MYKONOS_IP); drone_nav.sin_port = htons(NAVDATA_PORT); if(bind( navdata_socket, (struct sockaddr *)&pc_addr, sizeof(pc_addr)) < 0){ printf ("bind: %s\n", strerror(errno)); goto fail; }; //set unicast mode on sendto(navdata_socket, trig, 4, 0, (struct sockaddr *)&drone_nav, sizeof(drone_nav)); int n=0; while ( 1 ) { if(seq<2) sprintf(command,"AT*CONFIG=%d,\"general:navdata_demo\",\"TRUE\"\r",seq); else sprintf(command,"AT*COMWDG=%d\r",seq); sendto(at_socket, command, strlen(command), 0, (struct sockaddr*)&drone_at, sizeof(drone_at) ); seq++; size=0; //sockaddr_in client_addr; int l = sizeof(pc_addr); size = recvfrom ( navdata_socket, &msg[0], NAVDATA_BUFFER_SIZE, 0, (struct sockaddr *)&from, &l); //printf("\33[2J\nread %d data ",size); //for(l=24;l<28;l++) n++; if (n>5) { printf("vbat_flying_percentage %i \n",0xff & msg[24]); n=0; } //sprintf( "Digits 10 equal:\n Hex: %i Octal: %i Decimal: %i\n", msg[24], msg[24], msg[24] ); Sleep(200); } fail: return 0; }
#58
Отправлено 07.04.2013, 09:27:32
![](https://vse.kz/public/style_images/osnovnoi34/post_offline.png)
http://robocraft.ru/...5.html#comments
Робот-андроид PETMAN, от Boston Dynamics готов к выполнению своих служебных обязанностей
http://www.youtube.com/watch?v=tFrjrgBV8K0
Робот-андроид PETMAN, от Boston Dynamics готов к выполнению своих служебных обязанностей
http://www.youtube.com/watch?v=tFrjrgBV8K0
Количество пользователей, читающих эту тему: 3
пользователей: 0, неизвестных прохожих: 3, скрытых пользователей: 0