HiHope开发者社区
直播中

zzb天明

3年用户 3经验值
私信 关注
[经验]

鸿蒙HarmonyOS 结合 大疆Tello TT无人机 开启智能家居物联网新模式

利用鸿蒙Hispark WIFI IOT 套件控制大疆TELLO 无人机


具体的思路如下:


第一步:查看无人机通信协议:
(无人机SDK连接:https://dl.djicdn.com/downloads/RoboMaster%20TT/Tello_SDK_3.0_User_Guide.pdf)


第二步:结合鸿蒙UDP网络编程相关部分写入无人机的wifi名称,密码,ip地址,端口

1
2
3
4
5
6
7
8
9
10
11
12
#ifndef NET_PARAMS_H
#define NET_PARAMS_H

#define PARAM_HOTSPOT_SSID "TELLO-TELLO-60BA0A"   // your AP SSID
#define PARAM_HOTSPOT_PSK  "12345678"  // your AP PSK

#define PARAM_HOTSPOT_TYPE WIFI_SEC_TYPE_PSK // defined in wifi_device_config.h

#define PARAM_SERVER_ADDR "192.168.10.1" // your PC IP address
#define PARAM_SERVER_PORT 8889

#endif  // NET_PARAMS_H



第三步:查看无人机开放的SDK得知相关的命令

第四步:编写客户端代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include
#include
#include
#include
#include "udp_client_test.h"
#include "net_common.h"
static char response[128] = "";

void UdpClientTest(const char* host, unsigned short port)
{
    ssize_t retval = 0;
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0); // UDP socket

    struct sockaddr_in toAddr = {0};
    toAddr.sin_family = AF_INET;
    toAddr.sin_port = htons(port); // 端口号,从主机字节序转为网络字节序
    if (inet_pton(AF_INET, host, &toAddr.sin_addr) <= 0) { // 将主机IP地址从“点分十进制”字符串 转化为 标准格式(32位整数)
        printf("inet_pton failed!rn");
        goto do_cleanup;
    }

    // UDP socket 是 “无连接的” ,因此每次发送都必须先指定目标主机和端口,主机可以是多播地址
    //从这里开始给无人机发送SDK中的指令,控制无人机
    retval = sendto(sockfd, "command", sizeof("command"), 0, (struct sockaddr *)&toAddr, sizeof(toAddr));
    printf("send UDP message {%s} %ld done!rn","command", retval);
    osDelay(500);

    retval = sendto(sockfd, "takeoff", sizeof("takeoff"), 0, (struct sockaddr *)&toAddr, sizeof(toAddr));
    printf("send UDP message {%s} %ld done!rn","takeoff", retval);
    osDelay(800);

    retval = sendto(sockfd, "up 50", sizeof("up 50"), 0, (struct sockaddr *)&toAddr, sizeof(toAddr));
    printf("send UDP message {%s} %ld done!rn","up 50", retval);
    osDelay(500);

    retval = sendto(sockfd, "flip r", sizeof("flip r"), 0, (struct sockaddr *)&toAddr, sizeof(toAddr));
    printf("send UDP message {%s} %ld done!rn","flip r", retval);
    osDelay(800);
    retval = sendto(sockfd, "cw 360", sizeof("cw 360"), 0, (struct sockaddr *)&toAddr, sizeof(toAddr));
    printf("send UDP message {%s} %ld done!rn","cw 360", retval);
    osDelay(800);
    retval = sendto(sockfd, "ccw 360", sizeof("ccw 360"), 0, (struct sockaddr *)&toAddr, sizeof(toAddr));
    printf("send UDP message {%s} %ld done!rn","ccw 360", retval);
    osDelay(500);
    retval = sendto(sockfd, "flip r", sizeof("flip l"), 0, (struct sockaddr *)&toAddr, sizeof(toAddr));
    printf("send UDP message {%s} %ld done!rn","flip r", retval);
    osDelay(800);
    retval = sendto(sockfd, "left 80", sizeof("left 80"), 0, (struct sockaddr *)&toAddr, sizeof(toAddr));
    printf("send UDP message {%s} %ld done!rn","left 80", retval);
    osDelay(500);
    retval = sendto(sockfd, "right 80", sizeof("right 80"), 0, (struct sockaddr *)&toAddr, sizeof(toAddr));
    printf("send UDP message {%s} %ld done!rn","right 80", retval);
    osDelay(500);
    retval = sendto(sockfd, "land", sizeof("land"), 0, (struct sockaddr *)&toAddr, sizeof(toAddr));
    printf("send UDP message {%s} %ld done!rn","land", retval);


    struct sockaddr_in fromAddr = {0};
    socklen_t fromLen = sizeof(fromAddr);

    // UDP socket 是 “无连接的” ,因此每次接收时前并不知道消息来自何处,通过 fromAddr 参数可以得到发送方的信息(主机、端口号)
    retval = recvfrom(sockfd, &response, sizeof(response), 0, (struct sockaddr *)&fromAddr, &fromLen);
    if (retval <= 0) {
        printf("recvfrom failed or abort, %ld, %d!rn", retval, errno);
        goto do_cleanup;
    }
    response[retval] = '\0';
    printf("recv UDP message {%s} %ld done!rn", response, retval);
    printf("peer info: ipaddr = %s, port = %drn", inet_ntoa(fromAddr.sin_addr), ntohs(fromAddr.sin_port));

do_cleanup:
    printf("do_cleanup...rn");
    close(sockfd);
}



第五步:把两个BUILD.gn文件里面内容检测完毕,即可进入编译
运行:python build.py wifiiot 看到BUILD SUCCESS,基本大工告成!
第六步:开机测试,附上串口打印的信息



总体上还好,不过还存在指令在传输过程中丢失的情况,5个命令,有时候传过去了4个或者3个。
这个项目今后的开发思路:
1.加入开发板的键盘控制无人机,并且结合OLED屏幕,把每次的指令打印到屏幕中
2.开发板控制多机编队飞行
3.后面如果有 HiSpark Wi-Fi IoT智能小车 的话,结合无人机和小车一块执行任务
鸿蒙网络编程,本案例只是控制无人机的,其实基本是机器人,我觉得都可以通信,毕竟万物相连
学习链接如下:许老师课程:https://edu.51cto.com/course/25739.html?hm

HARMony OS进行网络编程 demo链接:https://gitee.com/hihopeorg/HarmonyOS-IoT-Application-Development/tree/master/05_network




最后附上本demo视频链接:


https://www.bilibili.com/video/BV1454y167sz/

更多回帖

发帖
×
20
完善资料,
赚取积分