diff options
author | 2024-06-11 22:10:20 +0800 | |
---|---|---|
committer | 2024-06-11 22:10:20 +0800 | |
commit | 7eba07d667cf1a7613fed1170e884a3a43123fe1 (patch) | |
tree | c6c1e0f9155913ea3c3a4420b22a64ffafeed24f | |
parent | d746146529490663993e489de21d0c15e2d234ad (diff) | |
download | WheelCtrl-7eba07d667cf1a7613fed1170e884a3a43123fe1.tar.gz WheelCtrl-7eba07d667cf1a7613fed1170e884a3a43123fe1.zip |
wheel ctrl finished, can use udpserver ctrl wheel
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | CMakeLists.txt | 17 | ||||
-rw-r--r-- | README.md | 8 | ||||
-rwxr-xr-x | lib/liblcm.so | bin | 0 -> 144320 bytes | |||
-rw-r--r-- | serial.c | 20 | ||||
-rw-r--r-- | udp2lcm.c | 26 |
6 files changed, 60 insertions, 12 deletions
@@ -1,2 +1,3 @@ | |||
1 | build/* | 1 | build/* |
2 | bin/* | ||
2 | .vscode/* \ No newline at end of file | 3 | .vscode/* \ No newline at end of file |
diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..da5fc52 --- /dev/null +++ b/CMakeLists.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | cmake_minimum_required(VERSION 3.10) | ||
2 | project(WheelCtrl) | ||
3 | |||
4 | # Set the output directory for the build executables. | ||
5 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin) | ||
6 | add_compile_options(-g -w) | ||
7 | |||
8 | # Find the required libraries | ||
9 | find_library(LCM_LIBRARY lcm lib) | ||
10 | |||
11 | # Add the executable serial | ||
12 | add_executable(serial serial.c path/path_ctrl_t.c) | ||
13 | target_link_libraries(serial ${LCM_LIBRARY}) | ||
14 | |||
15 | # Add the executable udp2lcm | ||
16 | add_executable(udp2lcm udp2lcm.c path/path_ctrl_t.c) | ||
17 | target_link_libraries(udp2lcm ${LCM_LIBRARY}) \ No newline at end of file | ||
diff --git a/README.md b/README.md new file mode 100644 index 0000000..b00f48f --- /dev/null +++ b/README.md | |||
@@ -0,0 +1,8 @@ | |||
1 | 这是ohos项目中关于udp与lcm互转服务器、以及轮子控制的代码。 | ||
2 | |||
3 | # 功能说明 | ||
4 | - udp2lcm.c是udp与lcm互转服务器的代码,该服务器负责: | ||
5 | - 接收来自手机端的udp包,解析其命令,发布到对应的lcm通道,供轮子控制模块或算法模块使用 | ||
6 | - 将所有来自算法模块或轮子控制模块的lcm包,转发到手机端 | ||
7 | - 必要的其他功能,如心跳包的更新与发送、拉起http服务器等 | ||
8 | - serial.c串口通信,是轮子控制模块,接收来自对应信道的lcm命令,解析其命令后发送到轮子的驱动板,控制轮子的转动 \ No newline at end of file | ||
diff --git a/lib/liblcm.so b/lib/liblcm.so new file mode 100755 index 0000000..cb18db8 --- /dev/null +++ b/lib/liblcm.so | |||
Binary files differ | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | typedef unsigned char byte; | 11 | typedef unsigned char byte; |
12 | #define MAX_BUFFER_SIZE 1024 | 12 | #define MAX_BUFFER_SIZE 1024 |
13 | #define DEFAULT_SPEED 0x15 | ||
13 | 14 | ||
14 | int fd; // 轮子的串口文件描述符 | 15 | int fd; // 轮子的串口文件描述符 |
15 | char portname[50] = "/dev/ttyUSB0"; // 串口设备名 | 16 | char portname[50] = "/dev/ttyUSB0"; // 串口设备名 |
@@ -19,18 +20,24 @@ struct termios tty; | |||
19 | bool whellInit(); | 20 | bool whellInit(); |
20 | bool wheelSend(byte a, byte a_v, byte b, byte b_v); | 21 | bool wheelSend(byte a, byte a_v, byte b, byte b_v); |
21 | void speedControl(byte status, byte speed); | 22 | void speedControl(byte status, byte speed); |
22 | void parseCmd(const path_ctrl_t *msg, void *user); | 23 | void parseCmd(const lcm_recv_buf_t *rbuf, const char *channel, |
24 | const path_ctrl_t *msg, void *userdata); | ||
23 | 25 | ||
24 | int main() { | 26 | int main() { |
25 | if (!whellInit()) { | 27 | if (!whellInit()) { |
26 | goto err; | 28 | goto err; |
27 | } | 29 | } |
28 | lcm *path_lcm = lcm_create(NULL); | 30 | lcm_t *path_lcm = lcm_create(NULL); |
29 | if (!path_lcm) { | 31 | if (!path_lcm) { |
30 | fprintf(stderr, "Failed to create LCM\n"); | 32 | fprintf(stderr, "Failed to create LCM\n"); |
31 | goto err; | 33 | goto err; |
32 | } | 34 | } |
33 | path_ctrl_t_subscribe(path_lcm, "PATH_CTRL", parseCmd); | 35 | path_ctrl_t cmd; |
36 | path_ctrl_t_subscribe(path_lcm, "wheel_ctrl", parseCmd, &cmd); | ||
37 | |||
38 | while (true) { | ||
39 | lcm_handle(path_lcm); | ||
40 | } | ||
34 | 41 | ||
35 | err: | 42 | err: |
36 | close(fd); | 43 | close(fd); |
@@ -102,17 +109,18 @@ bool wheelSend(byte a, byte a_v, byte b, byte b_v) { | |||
102 | return true; | 109 | return true; |
103 | } | 110 | } |
104 | 111 | ||
105 | void parseCmd(const path_ctrl_t *msg, void *user) { | 112 | void parseCmd(const lcm_recv_buf_t *rbuf, const char *channel, |
113 | const path_ctrl_t *msg, void *userdata) { | ||
106 | byte status = msg->cmd, speed = msg->speed; | 114 | byte status = msg->cmd, speed = msg->speed; |
107 | switch (status) { | 115 | switch (status) { |
108 | case 1: | 116 | case 1: |
109 | wheelSend(0x01, speed, 0x01, speed); | 117 | wheelSend(0x01, speed, 0x01, speed); |
110 | break; | 118 | break; |
111 | case 2: | 119 | case 2: |
112 | wheelSend(0x02, speed, 0x01, speed); | 120 | wheelSend(0x02, DEFAULT_SPEED, 0x01, DEFAULT_SPEED); |
113 | break; | 121 | break; |
114 | case 3: | 122 | case 3: |
115 | wheelSend(0x01, speed, 0x02, speed); | 123 | wheelSend(0x01, DEFAULT_SPEED, 0x02, DEFAULT_SPEED); |
116 | break; | 124 | break; |
117 | case 0: | 125 | case 0: |
118 | default: | 126 | default: |
@@ -10,9 +10,19 @@ | |||
10 | * cmd为0停,1前,2左,3右 | 10 | * cmd为0停,1前,2左,3右 |
11 | */ | 11 | */ |
12 | #include "path/path_ctrl_t.h" | 12 | #include "path/path_ctrl_t.h" |
13 | #include <arpa/inet.h> | ||
14 | #include <errno.h> | ||
15 | #include <fcntl.h> | ||
16 | #include <netinet/in.h> | ||
17 | #include <poll.h> | ||
18 | #include <pthread.h> | ||
19 | #include <stdbool.h> | ||
13 | #include <stdio.h> | 20 | #include <stdio.h> |
14 | #include <stdlib.h> | 21 | #include <stdlib.h> |
15 | #include <string.h> | 22 | #include <string.h> |
23 | #include <sys/socket.h> | ||
24 | #include <termios.h> | ||
25 | #include <unistd.h> | ||
16 | 26 | ||
17 | #define MAX_BUFFER_SIZE 1024 | 27 | #define MAX_BUFFER_SIZE 1024 |
18 | #define PORT 5001 | 28 | #define PORT 5001 |
@@ -37,6 +47,9 @@ int main() { | |||
37 | } | 47 | } |
38 | // 开启udp接收线程 | 48 | // 开启udp接收线程 |
39 | pthread_create(&udpRecv, NULL, udpRecvHandler, NULL); | 49 | pthread_create(&udpRecv, NULL, udpRecvHandler, NULL); |
50 | while (true) { | ||
51 | pause(); | ||
52 | } | ||
40 | return 0; | 53 | return 0; |
41 | } | 54 | } |
42 | 55 | ||
@@ -62,6 +75,7 @@ void udpRecvHandler() { | |||
62 | int retval; | 75 | int retval; |
63 | struct pollfd fds; | 76 | struct pollfd fds; |
64 | 77 | ||
78 | printf("udpRecvHandler\n"); | ||
65 | if ((socketfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { | 79 | if ((socketfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { |
66 | fprintf(stderr, "Error: Failed to create socket\n"); | 80 | fprintf(stderr, "Error: Failed to create socket\n"); |
67 | return; | 81 | return; |
@@ -69,7 +83,7 @@ void udpRecvHandler() { | |||
69 | memset((char *)&serverAddr, 0, sizeof(serverAddr)); | 83 | memset((char *)&serverAddr, 0, sizeof(serverAddr)); |
70 | memset(buffer, 0, sizeof(buffer)); | 84 | memset(buffer, 0, sizeof(buffer)); |
71 | serverAddr.sin_family = AF_INET; | 85 | serverAddr.sin_family = AF_INET; |
72 | serverAddr.sin_port = htons(port); | 86 | serverAddr.sin_port = htons(PORT); |
73 | serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); | 87 | serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); |
74 | 88 | ||
75 | if (bind(socketfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == | 89 | if (bind(socketfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == |
@@ -107,7 +121,9 @@ void udpRecvHandler() { | |||
107 | break; | 121 | break; |
108 | } else if (retval == 0) { | 122 | } else if (retval == 0) { |
109 | printf("No data within three seconds.\n"); | 123 | printf("No data within three seconds.\n"); |
110 | speedControl(0, 0); | 124 | // out of 3s, stop the wheel |
125 | path_ctrl_t path = {0, 0}; | ||
126 | path_ctrl_t_publish(path_ctrl_lcm, "wheel_ctrl", &path); | ||
111 | } else { | 127 | } else { |
112 | bytesReceived = recvfrom(socketfd, buffer, MAX_BUFFER_SIZE, 0, | 128 | bytesReceived = recvfrom(socketfd, buffer, MAX_BUFFER_SIZE, 0, |
113 | (struct sockaddr *)&clientAddr, &addrLen); | 129 | (struct sockaddr *)&clientAddr, &addrLen); |
@@ -136,7 +152,7 @@ void udpSendHandler() { | |||
136 | 152 | ||
137 | memset((char *)&serverAddr, 0, sizeof(serverAddr)); | 153 | memset((char *)&serverAddr, 0, sizeof(serverAddr)); |
138 | serverAddr.sin_family = AF_INET; // 设置地址族为IPv4 | 154 | serverAddr.sin_family = AF_INET; // 设置地址族为IPv4 |
139 | serverAddr.sin_port = htons(port); // 设置端口号 | 155 | serverAddr.sin_port = htons(PORT); // 设置端口号 |
140 | if (inet_aton(clientIP, &serverAddr.sin_addr) == 0) { | 156 | if (inet_aton(clientIP, &serverAddr.sin_addr) == 0) { |
141 | fprintf(stderr, "Error: Failed to convert IP address\n"); | 157 | fprintf(stderr, "Error: Failed to convert IP address\n"); |
142 | close(sockfd); | 158 | close(sockfd); |
@@ -146,14 +162,13 @@ void udpSendHandler() { | |||
146 | while (true) { | 162 | while (true) { |
147 | sendto(sockfd, (const char *)heartBeat, 9, 0, | 163 | sendto(sockfd, (const char *)heartBeat, 9, 0, |
148 | (struct sockaddr *)&serverAddr, sizeof(serverAddr)); | 164 | (struct sockaddr *)&serverAddr, sizeof(serverAddr)); |
149 | printf("Send: Data %02x udpSend successfully!\n", a); | ||
150 | sleep(1); | 165 | sleep(1); |
151 | } | 166 | } |
152 | } | 167 | } |
153 | 168 | ||
154 | void parseCmd(const char *buffer, int bytesReceived) { | 169 | void parseCmd(const char *buffer, int bytesReceived) { |
155 | // TODO: 完成本函数的内容 | 170 | // TODO: 完成本函数的内容 |
156 | if (buffer == NULL || strlen(buffer) != 9) { | 171 | if (buffer == NULL) { |
157 | fprintf(stderr, "Error: Invalid message\n"); | 172 | fprintf(stderr, "Error: Invalid message\n"); |
158 | return; | 173 | return; |
159 | } | 174 | } |
@@ -179,6 +194,5 @@ void parseCmd(const char *buffer, int bytesReceived) { | |||
179 | */ | 194 | */ |
180 | } else if (buffer[0] == 3) { | 195 | } else if (buffer[0] == 3) { |
181 | // 手机发来的终点坐标,转发给算法模块 | 196 | // 手机发来的终点坐标,转发给算法模块 |
182 | ; | ||
183 | } | 197 | } |
184 | } \ No newline at end of file | 198 | } \ No newline at end of file |