aboutsummaryrefslogtreecommitdiffstats
path: root/udp2lcm/udp2lcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'udp2lcm/udp2lcm.c')
-rw-r--r--udp2lcm/udp2lcm.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/udp2lcm/udp2lcm.c b/udp2lcm/udp2lcm.c
new file mode 100644
index 0000000..fdf32c8
--- /dev/null
+++ b/udp2lcm/udp2lcm.c
@@ -0,0 +1,118 @@
1// Encoded in UTF-8
2
3/*
4 * struct path_ctrl_t
5 * {
6 * int8_t cmd;
7 * int8_t speed;
8 * }
9 * 这是与轮控模块通信的数据结构,speed为0-100表示速度
10 * cmd为0停,1前,2左,3右
11 */
12
13#include "udp2lcm.h"
14
15pthread_t udpRecv, udpSend;
16int8_t heartBeat[9] = {0};
17pthread_mutex_t heartBeatMutex;
18struct sockaddr_in clientAddr;
19char clientIP[20] = "";
20lcm_t *lcm;
21
22int main() {
23 if (!LCMInit()) {
24 fprintf(stderr, "Error: Failed to initialize LCM\n");
25 return -1;
26 }
27 // 初始化线程锁
28 pthread_mutex_init(&heartBeatMutex, NULL);
29 // 开启udp接收线程
30 pthread_create(&udpRecv, NULL, udpRecvHandler, NULL);
31 pid_t httpServerPid = -1;
32 if ((httpServerPid = fork()) == 0) {
33 // 拉起服务器进程,手机端需要申请的文件/mnt/cf/mapfile/defaultMap.txt
34 // ATTENTION: 这里的路径需要根据实际存储地图的路径来修改
35 chdir("/mnt/cf/mapfile/");
36 /*
37 * execlp使用系统调用exec()执行一个程序
38 * 第一个参数是文件名,将在PATH中查找,最后一个参数必须是NULL
39 * 其他的是传递过去的参数,按一般约定,第一个参数是程序名,不被使用
40 * 因而这里出现了两个python
41 */
42 execlp("python", "python", "-m", "http.server", NULL);
43 }
44 while (true) {
45 pause();
46 }
47 return 0;
48}
49
50bool LCMInit() {
51 if ((lcm = lcm_create("udpm://239.255.76.67:7667?ttl=1")) == NULL) {
52 fprintf(stderr, "Error: Failed to create Path Ctrl LCM\n");
53 return false;
54 }
55 return true;
56}
57
58void parseCmd(const char *buffer, int bytesReceived) {
59 if (buffer == NULL) {
60 fprintf(stderr, "Error: Invalid message\n");
61 return;
62 }
63
64 path_ctrl_t path;
65 robot_control_t robotCtrlData;
66 pose_t curPos;
67 if (buffer[0] == 0) {
68 // 手机端用来与udp2lcm服务器建立连接的初始化消息
69 // 也是手机端的心跳
70 ;
71 } else if (buffer[0] == 1) {
72 // 建图过程中,手机端遥控小车进行移动,命令下发至轮控模块
73 path.cmd = buffer[1];
74 path.speed = buffer[2];
75 path_ctrl_t_publish(lcm, "wheel_ctrl", &path);
76 } else if (buffer[0] == 2) {
77 /*
78 * 结束建图,主要有以下几个任务:
79 * - 向轮控模块发送停止命令
80 * - 通知算法模块结束建图
81 * - 拉起http服务器进程(改由main拉起,省的每次拉起浪费资源)
82 * - 向手机端通知建图完成
83 * 开始通过lcm接受算法给出的实时坐标,存储至heartBeat数组中(对应格式)
84 */
85 path.cmd = 0;
86 path.speed = 0;
87 path_ctrl_t_publish(lcm, "wheel_ctrl", &path);
88
89 robotCtrlInit(&robotCtrlData, 0, 32, 0, 0, 0, 0, 0);
90 robot_control_t_publish(lcm, "ROBOT_CONTROL", &robotCtrlData);
91
92 pose_t_subscribe(lcm, "CURRENTPOSE", poseHandler, NULL);
93 } else if (buffer[0] == 3) {
94 // 手机发来的终点坐标,转发给算法模块
95 }
96}
97
98void poseHandler(const lcm_recv_buf_t *rbuf, const char *channel,
99 const pose_t *msg, void *userdata) {
100 int16_t x, y, sita;
101 x = (int16_t)msg->pos[0];
102 y = (int16_t)msg->pos[1];
103 sita = (int16_t)msg->pos[2];
104 while (sita > 180)
105 sita -= 360;
106 while (sita < -180)
107 sita += 360;
108 pthread_mutex_lock(&heartBeatMutex);
109 heartBeat[0] = 0x03;
110 heartBeat[1] = heartBeat[2] = 0;
111 heartBeat[3] = x >> 8;
112 heartBeat[4] = x;
113 heartBeat[5] = y >> 8;
114 heartBeat[6] = y;
115 heartBeat[7] = sita >> 8;
116 heartBeat[8] = sita;
117 pthread_mutex_unlock(&heartBeatMutex);
118} \ No newline at end of file