diff options
Diffstat (limited to 'udp2lcm/udp.c')
-rw-r--r-- | udp2lcm/udp.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/udp2lcm/udp.c b/udp2lcm/udp.c new file mode 100644 index 0000000..6c4bd4a --- /dev/null +++ b/udp2lcm/udp.c | |||
@@ -0,0 +1,127 @@ | |||
1 | #include "udp2lcm.h" | ||
2 | |||
3 | void udpRecvHandler() { | ||
4 | int socketfd = -1; | ||
5 | char buffer[MAX_BUFFER_SIZE]; | ||
6 | struct sockaddr_in serverAddr; | ||
7 | socklen_t addrLen = sizeof(serverAddr); | ||
8 | int bytesReceived; | ||
9 | |||
10 | int retval; | ||
11 | struct pollfd fds; | ||
12 | |||
13 | printf("udpRecvHandler\n"); | ||
14 | if ((socketfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { | ||
15 | fprintf(stderr, "Error: Failed to create socket\n"); | ||
16 | return; | ||
17 | } | ||
18 | memset((char *)&serverAddr, 0, sizeof(serverAddr)); | ||
19 | memset(buffer, 0, sizeof(buffer)); | ||
20 | serverAddr.sin_family = AF_INET; | ||
21 | serverAddr.sin_port = htons(PORT); | ||
22 | serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); | ||
23 | |||
24 | if (bind(socketfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == | ||
25 | -1) { | ||
26 | fprintf(stderr, "Error: Bind failed\n"); | ||
27 | close(socketfd); | ||
28 | return; | ||
29 | } | ||
30 | |||
31 | bytesReceived = recvfrom(socketfd, buffer, MAX_BUFFER_SIZE, 0, | ||
32 | (struct sockaddr *)&clientAddr, &addrLen); | ||
33 | if (bytesReceived == -1) { | ||
34 | fprintf(stderr, "Error: Failed to receive data\n"); | ||
35 | close(socketfd); | ||
36 | return; | ||
37 | } | ||
38 | printf("Start message from %s: %s\n", inet_ntoa(clientAddr.sin_addr), | ||
39 | buffer); | ||
40 | strcpy(clientIP, inet_ntoa(clientAddr.sin_addr)); | ||
41 | |||
42 | /* | ||
43 | * 接收到来自手机端的第一条消息之后: | ||
44 | * - 启动udpSend线程,用于向手机端发送心跳信息 | ||
45 | * - 通过ROBOT_COMTROL信道向算法模块发送建图开始消息 | ||
46 | * - 7号命令初始坐标、初始角度、雷达扫描最大范围、机器人半径、机器人高 | ||
47 | * - 30号命令开始建图,参数为单个像素点大小 | ||
48 | */ | ||
49 | if (pthread_create(&udpSend, NULL, udpSendHandler, NULL) != 0) { | ||
50 | fprintf(stderr, "Error creating udpSend thread\n"); | ||
51 | close(socketfd); | ||
52 | exit(-1); | ||
53 | } | ||
54 | |||
55 | robot_control_t robotCtrlData; | ||
56 | robotCtrlInit(&robotCtrlData, 0, 7, 0, 7, 1, 0, 0); | ||
57 | robotCtrlData.iparams[0] = 1; | ||
58 | robot_control_t_publish(lcm, "ROBOT_CONTROL", &robotCtrlData); | ||
59 | freeRobotCtrl(&robotCtrlData); | ||
60 | // 随即下达30号命令,开始建图 | ||
61 | robotCtrlInit(&robotCtrlData, 0, 30, 0, 1, 1, 0, 0); | ||
62 | robotCtrlData.dparams[0] = 0.05; | ||
63 | robotCtrlData.niparams = 1; | ||
64 | robotCtrlData.iparams[0] = 1; | ||
65 | robot_control_t_publish(lcm, "ROBOT_CONTROL", &robotCtrlData); | ||
66 | freeRobotCtrl(&robotCtrlData); | ||
67 | |||
68 | /* | ||
69 | * 开始接收来自手机端的命令 | ||
70 | * 限定时间为3s,超过3s未收到消息则停止轮子 | ||
71 | * 但不退出循环,防止是网络抖动 | ||
72 | */ | ||
73 | const path_ctrl_t path = {0, 0}; // 就是停止命令,不能改 | ||
74 | fds.fd = socketfd; | ||
75 | fds.events = POLLIN; | ||
76 | while (true) { | ||
77 | retval = poll(&fds, 1, 3000); | ||
78 | if (retval == -1) { | ||
79 | fprintf(stderr, "Error: select failed\n"); | ||
80 | break; | ||
81 | } else if (retval == 0) { | ||
82 | // 超出3s,报错并停止前进 | ||
83 | fprintf(stderr, "No data within three seconds.\n"); | ||
84 | path_ctrl_t_publish(lcm, "wheel_ctrl", &path); | ||
85 | } else { | ||
86 | bytesReceived = recvfrom(socketfd, buffer, MAX_BUFFER_SIZE, 0, | ||
87 | (struct sockaddr *)&clientAddr, &addrLen); | ||
88 | if (bytesReceived == -1) { | ||
89 | fprintf(stderr, "Error: Failed to receive data\n"); | ||
90 | continue; | ||
91 | } | ||
92 | printf("Massage from client %s: ", clientIP); | ||
93 | for (int i = 0; i < bytesReceived; i++) { | ||
94 | printf("%02x ", buffer[i]); | ||
95 | } | ||
96 | printf("\n"); | ||
97 | parseCmd(buffer, bytesReceived); | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | |||
102 | void udpSendHandler() { | ||
103 | // 创建UDP套接字 | ||
104 | int sockfd = -1; | ||
105 | struct sockaddr_in serverAddr; | ||
106 | if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { | ||
107 | fprintf(stderr, "Error: Failed to create socket\n"); | ||
108 | return; | ||
109 | } | ||
110 | |||
111 | memset((char *)&serverAddr, 0, sizeof(serverAddr)); | ||
112 | serverAddr.sin_family = AF_INET; // 设置地址族为IPv4 | ||
113 | serverAddr.sin_port = htons(PORT); // 设置端口号 | ||
114 | if (inet_aton(clientIP, &serverAddr.sin_addr) == 0) { | ||
115 | fprintf(stderr, "Error: Failed to convert IP address\n"); | ||
116 | close(sockfd); | ||
117 | return; | ||
118 | } | ||
119 | |||
120 | while (true) { | ||
121 | pthread_mutex_lock(&heartBeatMutex); | ||
122 | sendto(sockfd, (const char *)heartBeat, 9, 0, | ||
123 | (struct sockaddr *)&serverAddr, sizeof(serverAddr)); | ||
124 | pthread_mutex_unlock(&heartBeatMutex); | ||
125 | sleep(1); | ||
126 | } | ||
127 | } \ No newline at end of file | ||