diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/README.docx b/AIOT/12182_Intelligent cooperative parking system for fleet/README.docx new file mode 100644 index 0000000000000000000000000000000000000000..c0e430ae0a5ec95f024b6eab8699bb35ec5a657e Binary files /dev/null and b/AIOT/12182_Intelligent cooperative parking system for fleet/README.docx differ diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/BUILD.gn b/AIOT/12182_Intelligent cooperative parking system for fleet/project/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..f901c6281c49f46a206dcdc00440ff69b0efcadf --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/BUILD.gn @@ -0,0 +1,16 @@ +static_library("project") { + sources = [ + "control_Main.c", + "control_TraceFollow.c", + "control_UltrasonicRanging.c", + "wifi_connecter.c" + ] + + include_dirs = [ + "./ssd1306", + "//utils/native/lite/include", + "//kernel/liteos_m/kal/cmsis", + "//base/iot_hardware/peripheral/interfaces/kits", + ] + deps = [ "ssd1306:oled_ssd1306" ] +} diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/Function_Should_Realize.c b/AIOT/12182_Intelligent cooperative parking system for fleet/project/Function_Should_Realize.c new file mode 100644 index 0000000000000000000000000000000000000000..20e02ec0d149610d2af7a372d2cc2d1ed73e6199 --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/Function_Should_Realize.c @@ -0,0 +1,129 @@ +#include +#include +#include +#include + +#include "lwip/sockets.h" +#include "ohos_init.h" +#include "cmsis_os2.h" +#include "iot_errno.h" +#include "lwip/netifapi.h" +#include "lwip/api_shell.h" +#include "NetConnection_parameters.h" + +#define NUM 1 +#define STACK_SIZE 1024 +#define QUEUE_SIZE 10 +typedef struct { + osThreadId_t thread_id; + char message_string[50]; +} message_entry; +osMessageQueueId_t queue_id; + +char g_request[50] = "HellowWorld"; +char g_response[50] = "HellowWorld"; + +//消息队列,支持两种操作: +// 1.查看当前消息队列中最早的一条消息 +// 2.删除当前消息队列中最早的一条消息 + +// 查看当前消息队列中最早的一条消息 + + +// 删除当前消息队列中最早的一条消息 + + +//下面的函数扔给一个线程来运行,负责接收消息,并把收到的消息(一个一个字符串)放进消息队列 + +//local_ip是本机的ip地址,local_port是接收消息的端口号 +void Test_TCP_MessageReceive(unsigned short port, const char* host) +{ + (void) host; + + int backlog = 1; + int sockfd = socket(AF_INET, SOCK_STREAM, 0); // TCP socket + struct sockaddr_in clientAddr = {0}; + socklen_t clientAddrLen = sizeof(clientAddr); + struct sockaddr_in serverAddr = {0}; + + // AF_INET represents IPv4 + serverAddr.sin_family = AF_INET; + // port number transformation + serverAddr.sin_port = htons(port); + //allow client to connect with werver + serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + + bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); + listen(sockfd, backlog); + int connfd = accept(sockfd, (struct sockaddr *)&clientAddr, &clientAddrLen); + // receive message + ssize_t retval = recv(connfd, g_request, sizeof(g_request), 0); + + g_request[retval] = '\0'; + printf("recv g_response{%s} %ld from server done!\r\n", g_response, retval); + lwip_close(sockfd); + +} + +//向ip地址为dst_ip的主机发送消息,消息发送到dst_port端口中,发送的字符串是msg +void Task_TCp_MessageSend(const char *host, unsigned short port) +{ + int sockfd = socket(AF_INET, SOCK_STREAM, 0); // TCP socket + struct sockaddr_in serverAddr = {0}; + // AF_INET represents IPv4 + serverAddr.sin_family = AF_INET; + // port number transformation + serverAddr.sin_port = htons(port); + // IP transformation + if (inet_pton(AF_INET, host, &serverAddr.sin_addr) <= 0) + lwip_close(sockfd); + // Try a connection + if (connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) + lwip_close(sockfd); + // After successful connection, send message + ssize_t retval = send(sockfd, g_request, sizeof(g_request), 0); + if (retval < 0) + lwip_close(sockfd); + + // end + lwip_close(sockfd); +} + +//这是共识算法的核心逻辑,由汪一奇完成,下面这段代码需要调用send_msg()、get()、pop()这三个函数 +void Task_MainBody() +{ + +} + +//运行共识算法 +//ip_address是当前小车的开发板的ip地址,port是接收消息的端口号 +void Thread_MessageReceive(int ip_address,int port) +{ + osThreadAttr_t attr2_MessageReceive; + + attr2_MessageReceive.name = "Task_MessageReceive"; + attr2_MessageReceive.attr_bits = 0U; + attr2_MessageReceive.cb_mem = NULL; + attr2_MessageReceive.cb_size = 0U; + attr2_MessageReceive.stack_mem = NULL; + attr2_MessageReceive.stack_size = 10240; + attr2_MessageReceive.priority = 24; + if (osThreadNew(Test_TCP_MessageReceive, NULL, &attr2_MessageReceive) == NULL) printf("Error: failed to creat thread MessageReceive\n"); + else printf("Success: creat MessageReceive"); +} + +void Thread_MessageSend(int ip_address,int port) +{ + osThreadAttr_t attr3_MessageSend; + + attr3_MessageSend.name = "Task_MessageSend"; + attr3_MessageSend.attr_bits = 0U; + attr3_MessageSend.cb_mem = NULL; + attr3_MessageSend.cb_size = 0U; + attr3_MessageSend.stack_mem = NULL; + attr3_MessageSend.stack_size = 10240; /* 堆栈大小为10240 */ + attr3_MessageSend.priority = 24; + + if (osThreadNew(Task_MainBody, NULL, &attr3_MessageSend.priority) == NULL) printf("Error: failed to creat thread MessageSend\n"); + else printf("Success: creat MessageSend"); +} diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/NetConnection_parameters.h b/AIOT/12182_Intelligent cooperative parking system for fleet/project/NetConnection_parameters.h new file mode 100644 index 0000000000000000000000000000000000000000..2fc617e8fbe961fffd39cd69be4eace94832da84 --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/NetConnection_parameters.h @@ -0,0 +1,32 @@ +#ifndef NET_PARAMS_H +#define NET_PARAMS_H + +#ifndef PARAM_HOTSPOT_SSID +#define PARAM_HOTSPOT_SSID "hispark" // your AP SSID +#endif + +#ifndef PARAM_HOTSPOT_PSK +#define PARAM_HOTSPOT_PSK "12345678" // your AP PSK +#endif + +#ifndef PARAM_HOTSPOT_TYPE +#define PARAM_HOTSPOT_TYPE WIFI_SEC_TYPE_PSK // defined in wifi_device_config.h +#endif + +#ifndef PARAM_SERVER_ADDR1 +#define PARAM_SERVER_ADDR1 "192.168.137.137" // server_1 IP address +#endif + +#ifndef PARAM_SERVER_PORT1 +#define PARAM_SERVER_PORT1 5678 // server_1 port +#endif + +#ifndef PARAM_SERVER_ADDR2 +#define PARAM_SERVER_ADDR2 "192.168.137.137" // server_2 IP address +#endif + +#ifndef PARAM_SERVER_PORT2 +#define PARAM_SERVER_PORT2 5678 // server_2 port +#endif + +#endif // NET_PARAMS_H \ No newline at end of file diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_01.c b/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_01.c new file mode 100644 index 0000000000000000000000000000000000000000..da808a3a4f664c5e395a5d60ad3397929ca717ae --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_01.c @@ -0,0 +1,454 @@ +#include +#include +#include +#include + +#ifndef NET_PARAMS_H +#define NET_PARAMS_H + +#ifndef PARAM_HOTSPOT_SSID +#define PARAM_HOTSPOT_SSID "hispark" // your AP SSID +#endif + +#ifndef PARAM_HOTSPOT_PSK +#define PARAM_HOTSPOT_PSK "12345678" // your AP PSK +#endif + +#ifndef PARAM_HOTSPOT_TYPE +#define PARAM_HOTSPOT_TYPE WIFI_SEC_TYPE_PSK // defined in wifi_device_config.h +#endif + +#ifndef PARAM_SERVER_ADDR1 +#define PARAM_SERVER_ADDR1 "192.168.137.137" // server_1 IP address +#endif + +#ifndef PARAM_SERVER_PORT1 +#define PARAM_SERVER_PORT1 5001 // server_1 port +#endif + +#ifndef PARAM_SERVER_ADDR2 +#define PARAM_SERVER_ADDR2 "192.168.137.137" // server_2 IP address +#endif + +#ifndef PARAM_SERVER_PORT2 +#define PARAM_SERVER_PORT2 5002 // server_2 port +#endif + +#ifndef PARAM_SERVER_ADDR3 +#define PARAM_SERVER_ADDR3 "192.168.137.137" // server_2 IP address +#endif + +#ifndef PARAM_SERVER_PORT3 +#define PARAM_SERVER_PORT3 5003 // server_2 port +#endif + +#endif // NET_PARAMS_H + + +char* IP_address(int x) +{ + if(x==1) + return PARAM_SERVER_ADDR1; + else if(x==2) + return PARAM_SERVER_ADDR2; + else if(x==3) + return PARAM_SERVER_ADDR3; +} +unsigned short PORT(int x) +{ + if(x==1) + return PARAM_SERVER_PORT1; + else if(x==2) + return PARAM_SERVER_PORT2; + else if(x==3) + return PARAM_SERVER_PORT3; +} + + + +const int node_total_number=3;//将其设为常量,以至于可以给结构体初始化 + +int port_car_01=5001; +int port_car_02=5002; +int port_car_03=5003; + +int my_node_identifier=1; + +int my_state=0; +int my_term=1; +int my_leader=-1; +int leader_term=-1; + +int HeartBeat_received=0; + + + +char* str_type(char* input_string) +{ + char *t1="HeartBeat"; + char *t2="give me a vote"; + char *t3="give you a vote"; + char *t4="not a standard message"; + if(strncmp(input_string,t1,9)==0) + return t1; + else if(strncmp(input_string,t2,14)==0) + return t2; + else if(strncmp(input_string,t3,15)==0) + return t3; + return t4; +} +int str_identifier(char* input_string) +{ + int len=strlen(input_string); + int v1,v2; + v1=input_string[len-6]-'0'; + v2=input_string[len-5]-'0'; + return v1*10+v2; +} +int str_term(char* input_string) +{ + int len=strlen(input_string); + int v1,v2,v3; + v1=input_string[len-3]-'0'; + v2=input_string[len-2]-'0'; + v3=input_string[len-1]-'0'; + return v1*100+v2*10+v3; +} +char* charToString(char ch) +{ + //这里必须设置为静态变量,否则局部变量会被销毁 + static char temp_str[2]; + temp_str[0] = ch; + temp_str[1] = '\0'; + return temp_str; +} +char* get_id_and_term(int id,int term) +{ + //这里必须设置为静态变量,否则局部变量会被销毁 + static char res[50]=""; + res[0]='\0';//清空字符串 + if(id<10) + { + strcat(res,"0"); + strcat(res,charToString('0'+id)); + } + else + { + strcat(res,charToString('0'+id/10)); + strcat(res,charToString('0'+id%10)); + } + strcat(res,"."); + if(term<10) + { + strcat(res,"00"); + strcat(res,charToString('0'+term)); + } + else if(term<100) + { + strcat(res,"0"); + strcat(res,charToString('0'+term/10)); + strcat(res,charToString('0'+term%10)); + } + else + { + strcat(res,charToString('0'+term/100)); + strcat(res,charToString('0'+term%100/10)); + strcat(res,charToString('0'+term%10)); + } + return res; +} + +struct Campaign_Msg_List +{ + //舍弃第[0]个空间,从第[1]个空间开始存数据 + int L,R; + int id[500],term[500]; +}list={1,0}; + +struct Ballot_Set +{ + int len; + int ballot_status[110]; + +}set={node_total_number}; + +void list_append(char *str) +{ + list.R++; + list.id[list.R]=str_identifier(str); + list.term[list.R]=str_term(str); +} +void list_pop_front() +{ + list.L++; +} +int list_get_id() +{ + return list.id[list.L]; +} +int list_get_term() +{ + return list.term[list.L]; +} +int list_size() +{ + return list.R-list.L+1; +} + +void set_clear() +{ + for(int i=0;i<=105;i++) + set.ballot_status[i]=0; +} +int set_count() +{ + int cnt=0; + for(int i=0;i<=105;i++) + if(set.ballot_status[i]==1) + cnt++; + return cnt; +} +void set_add(int x) +{ + set.ballot_status[x]=1; +} +void set_remove(int x) +{ + set.ballot_status[x]=0; +} + +int rand_int(int L,int R) +{ + int x=rand()%(R-L+1); + x=x+L; + return x; +} + + +//void receive_msg(int local_ip,int local_port) +void receive_msg(int local_id) +{ + char *local_ip=IP_address(local_id); + int local_port=PORT(local_id); + Test_TCP_MessageReceive(local_ip,local_port); + //将buffer中的值赋值给receive_string + char *receive_string;//将消息收到的字符串存到这个指针指向的位置 + printf("Received string:%s\n", received_string); + if( strncmp(str_type(received_string),"HeartBeat") ) + { + HeartBeat_received=1; + int HeartBeat_term=str_term(received_string); + //旧leader看到新leader自动退位 + if(my_state==2 && my_term0) + { + while(list_size()) + { + int campaign_id=list_get_id(); + int campaign_term=list_get_term(); + list_pop_front(); + if(my_state==0) + { + if(campaign_term>=my_term+1) + { + my_term=campaign_term + dst_id=campaign_idl + char* str_info=get_id_and_term(my_node_identifier,my_term); + char* sending_msg="give you a vote, I am "; + strcat(sending_msg,str_info); + send_msg(sending_msg,i); + return 1; + } + } + else if(my_state==1) + { + if(campaign_term>=my_term+1) + my_state=0; + my_term=campaign_term; + return 2; + } + } + } + return 0; +} + + +int check_HeartBeat() +{ + if(HeartBeat_received==1) + { + HeartBeat_received=0; + return 1; + } + if(vote_for_candidate()==1) + return 1; + return 0; +} + + +void run_follower() +{ + int T1,T2,timeout_ms,run_time_ms; + timeout_ms=rand_int(4000,8000); + T1=clock(); + while(1) + { + if(check_HeartBeat()) + T1=clock(); + else + { + T2=clock(); + run_time_ms=T2-T1; + if(run_time_msnode_total_number/2) + { + my_state=2; + my_leader=my_node_identifier; + leader_term=my_term; + return; + } + T2=clock(); + run_time_ms=T2-T1; + if(run_time_ms>timeout_ms) + { + my_state=0; + return; + } + } +} + +void run_leader() +{ + while(1) + { + if(my_state==0) + return; + for(int i=1;i<=node_total_number) + { + if(i==my_node_identifier) + continue; + char* str_info=get_id_and_term(my_node_identifier,my_term); + char* sending_msg="HeartBeat, I am "; + strcat(sending_msg,str_info); + send_msg(sending_msg,i); + } + osDelay(200);//我也不知道单位是ms还是s,先认为是ms,以及要注意引入头文件 + } +} + + + + +void raft_kernel() +{ + while(1) + { + print("my_state:%s",charToString('0'+my_state)); + if(my_state==0) + run_follower(); + else if(my_state==1) + run_candidate(); + else if(my_state==2) + run_leader(); + } +} + + + + + + +void Thread_Management(void) +{ + osThreadAttr_t attr1; + + attr1.name = "BasicControl"; + attr1.attr_bits = 0U; + attr1.cb_mem = NULL; + attr1.cb_size = 0U; + attr1.stack_mem = NULL; + attr1.stack_size = 10240; + attr1.priority = 25; + + if (osThreadNew(Task_BasicControl, NULL, &attr1) == NULL) printf("Error:failed to create BasicControl!\n"); + + + osThreadAttr_t attr2; + + attr2.name = "NetDemoTask"; + attr2.attr_bits = 0U; + attr2.cb_mem = NULL; + attr2.cb_size = 0U; + attr2.stack_mem = NULL; + attr2.stack_size = 10240; /* 堆栈大小为10240 */ + attr2.priority = 24; + + if (osThreadNew(Task_NetConnection, NULL, &attr2) == NULL) printf("Error: failed to create NetConnection\n"); +} +APP_FEATURE_INIT(Thread_Management); \ No newline at end of file diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_01.py b/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_01.py new file mode 100644 index 0000000000000000000000000000000000000000..cd3621187f0449281708795feccbb7b7660dfaee --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_01.py @@ -0,0 +1,274 @@ +import random +import time +from concurrent.futures import ThreadPoolExecutor +from flask import Flask, request +import requests +import threading + +node_total_number=3 +port_car_01=5001 +port_car_02=5002 +port_car_03=5003 + +my_node_identifier=1 + +my_state=0 +my_term=1 +my_leader=-1 +leader_term=-1 + + +HeartBeat_received=False +campaign_msg_list=[] #收到的竞选节点列表,存的是参加竞选的节点的编号,用列表存储是因为需要关注节点的顺序 +ballot_set=set() #follower给自己的投票,存的是投票节点的编号 + +class str_parse: + def type(self,msg): + if(msg[0:9]=='HeartBeat'): + return 'HeartBeat' + elif(msg[0:14]=='give me a vote'): + return 'give me a vote' + elif(msg[0:15]=='give you a vote'): + return 'give you a vote' + else: + return 'not a standard message' + def identifier(self,msg): + t=msg[-6:-4] + return int(t) + def term(self,msg): + t=msg[-3:] + return int(t) + def get_id_and_term(self,id, term): + if (id < 10): + str_node_identifier = "0" + str(id) + else: + str_node_identifier = str(id) + if (term < 10): + str_term = '00' + str(term) + elif (term < 100): + str_term = '0' + str(term) + else: + str_term = str(term) + return str_node_identifier+"."+str_term + + +app = Flask(__name__) + +def receive_msg(): + strp=str_parse() + while True: + # 这里可以编写接收字符串的逻辑 + # 例如,可以使用 Flask 的路由和装饰器来定义字符串的处理函数 + @app.route('/receive', methods=['POST']) + def handle_string(): + global leader_term + global my_leader + global my_state + global my_term + global HeartBeat_received + global ballot_set + + received_string = request.form.get('string') + # 处理接收到的字符串 + print("Received string:", received_string) + if(strp.type(received_string)=='HeartBeat'): + HeartBeat_received = True + HearBeat_term=strp.term(received_string) + #旧leader看到新leader自动退位 + if(my_state==2 and my_term int: + global my_state + global my_term + strp = str_parse() + + if (my_state < 2 and len(campaign_msg_list)): + while (len(campaign_msg_list)): + item = campaign_msg_list[0] + campaign_msg_list.pop(0) + campaign_id = item[0] + campaign_term = item[1] + # candidate的term+1在实现上是先发消息,后+1,因此下面的判断是二者任期相等 + # follower收到第一个任期与自己相等的candidate的消息就会term+1 + # 通过任期判断保证follower只给其中一个candidate投票 + if(my_state==0): + #一定是投票才会更新自己的任期(通常是+1),而每个节点在一个任期内不会重复投票 + #节点在同一个任期内不重复投票通过判断任期来限制 + if (campaign_term>=my_term+1): + my_term = campaign_term + dst_port = 5000 + campaign_id + str_info = strp.get_id_and_term(my_node_identifier, my_term) + sending_msg = "give you a vote, I am " + str_info + send_msg(sending_msg, dst_port) + return 1 + #candidate给自己投票,但仍然需要处理遇到更高任期的candidate的情况 + elif(my_state==1): + if(campaign_term>=my_term+1): + my_state=0 + my_term=campaign_term + return 2 + # 这样实现也不是不行,就是return太慢了,可能会导致candidate有点多,震荡更久 + return 0 + + + + +#检查来自leader的心跳,candidate的竞选投票也被视作心跳 +#设定一个存储空间,来存心跳,如果存储空间中有心跳则清空心跳并返回True,否则返回False +#同时还要处理投票消息并投票 +def check_HeartBeat() -> bool: + #print('T1') + global my_term + global HeartBeat_received + if(HeartBeat_received==True): + HeartBeat_received=False + return True + if(vote_for_candidate()==1): + return True + return False + + +class raft: + def follower(self): + global my_state + global my_term + + + timeout_ms = random.randint(4000, 8000) + + + T1 = time.time() #计时开始 + + while(True): + #只有收到心跳就会重置timeout,无论心跳来自leader还是来自candidate + if(check_HeartBeat()): + T1 = time.time() #重新开始计时 + else: + T2 = time.time() + run_time_ms=(T2-T1)*1000 + if(run_time_ms>timeout_ms): + my_state=1 + return + + def candidate(self): + global my_state + global my_term + global my_leader + global leader_term + global HeartBeat_received + global ballot_set + + + my_term=my_term+1 + + strp = str_parse() + ballot_set = set() + timeout_ms = random.randint(1500, 3000) + T1 = time.time() # 计时开始 + + while(True): + #接收消息的线程看到有新leader出现就会改动my_state + if(my_state==0): + return + # 尽量让candidate给第一个收到竞选消息的节点投票而不是强制给自己投票,这样可以加快共识速度 + # 我看大佬的实现是给自己投票,那我也给自己投票吧,因为candidate给其他candidate投票会涉及任期问题,给自己投票可以避免问题复杂化 + for i in range(1, node_total_number + 1): + if(i==my_node_identifier): + continue + str_info = strp.get_id_and_term(my_node_identifier, my_term) + sending_msg = 'give me a vote, I am ' + str_info + send_msg(sending_msg, 5000 + i) + # 遇到更新任期的节点自动变回follower + if(vote_for_candidate()==2): + if(my_state==0): + return + # 等待一段时间来接收来自节点的投票,并把收到的选票信息放进ballot_set + # code + #print("T3") + if(HeartBeat_received==True): + my_state=0 + HeartBeat_received=False + return + #print("T4") + if( len(ballot_set)+1 > node_total_number / 2 ): + my_state=2 + my_leader=my_node_identifier + leader_term=my_term + return + #print("T5") + T2 = time.time() + run_time_ms = (T2 - T1) * 1000 + #print("T6") + if (run_time_ms > timeout_ms): + my_state = 0 + return + + + # 发送心跳给其他所有节点,包括所有candidate和所有follower,无视来自candidate的选票消息,用心跳回复它即可 + def leader(self): + global my_state + global my_leader + sending_period=200 + while(True): + # 接收消息的线程看到有新leader出现,就会改动my_term + if (my_state==0): + return + for i in range(1,node_total_number+1): + if i==my_node_identifier: + continue + strp=str_parse() + str_info=strp.get_id_and_term(my_node_identifier,my_term) + sending_msg="HeartBeat, I am "+str_info + send_msg(sending_msg,5000+i) + threading.Event().wait(sending_period/1000) + + +def run_raft(): + raft_instance=raft() + while(True): + print("my_state:" + str(my_state)) + if(my_state==0): + raft_instance.follower() + elif(my_state==1): + raft_instance.candidate() + elif(my_state==2): + raft_instance.leader() + else: + print("state error") + break + + +if __name__=='__main__': + # 创建线程池 + with ThreadPoolExecutor(max_workers=2) as executor: + # 提交接收字符串的任务给线程池 + executor.submit(receive_msg) + # 提交发送字符串的任务给线程池 + executor.submit(run_raft) diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_02.c b/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_02.c new file mode 100644 index 0000000000000000000000000000000000000000..83b5bce41e322d35bc55637eeeacc68c04f476aa --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_02.c @@ -0,0 +1,454 @@ +#include +#include +#include +#include + +#ifndef NET_PARAMS_H +#define NET_PARAMS_H + +#ifndef PARAM_HOTSPOT_SSID +#define PARAM_HOTSPOT_SSID "hispark" // your AP SSID +#endif + +#ifndef PARAM_HOTSPOT_PSK +#define PARAM_HOTSPOT_PSK "12345678" // your AP PSK +#endif + +#ifndef PARAM_HOTSPOT_TYPE +#define PARAM_HOTSPOT_TYPE WIFI_SEC_TYPE_PSK // defined in wifi_device_config.h +#endif + +#ifndef PARAM_SERVER_ADDR1 +#define PARAM_SERVER_ADDR1 "192.168.137.137" // server_1 IP address +#endif + +#ifndef PARAM_SERVER_PORT1 +#define PARAM_SERVER_PORT1 5001 // server_1 port +#endif + +#ifndef PARAM_SERVER_ADDR2 +#define PARAM_SERVER_ADDR2 "192.168.137.137" // server_2 IP address +#endif + +#ifndef PARAM_SERVER_PORT2 +#define PARAM_SERVER_PORT2 5002 // server_2 port +#endif + +#ifndef PARAM_SERVER_ADDR3 +#define PARAM_SERVER_ADDR3 "192.168.137.137" // server_2 IP address +#endif + +#ifndef PARAM_SERVER_PORT3 +#define PARAM_SERVER_PORT3 5003 // server_2 port +#endif + +#endif // NET_PARAMS_H + + +char* IP_address(int x) +{ + if(x==1) + return PARAM_SERVER_ADDR1; + else if(x==2) + return PARAM_SERVER_ADDR2; + else if(x==3) + return PARAM_SERVER_ADDR3; +} +unsigned short PORT(int x) +{ + if(x==1) + return PARAM_SERVER_PORT1; + else if(x==2) + return PARAM_SERVER_PORT2; + else if(x==3) + return PARAM_SERVER_PORT3; +} + + + +const int node_total_number=3;//将其设为常量,以至于可以给结构体初始化 + +int port_car_01=5001; +int port_car_02=5002; +int port_car_03=5003; + +int my_node_identifier=2; + +int my_state=0; +int my_term=1; +int my_leader=-1; +int leader_term=-1; + +int HeartBeat_received=0; + + + +char* str_type(char* input_string) +{ + char *t1="HeartBeat"; + char *t2="give me a vote"; + char *t3="give you a vote"; + char *t4="not a standard message"; + if(strncmp(input_string,t1,9)==0) + return t1; + else if(strncmp(input_string,t2,14)==0) + return t2; + else if(strncmp(input_string,t3,15)==0) + return t3; + return t4; +} +int str_identifier(char* input_string) +{ + int len=strlen(input_string); + int v1,v2; + v1=input_string[len-6]-'0'; + v2=input_string[len-5]-'0'; + return v1*10+v2; +} +int str_term(char* input_string) +{ + int len=strlen(input_string); + int v1,v2,v3; + v1=input_string[len-3]-'0'; + v2=input_string[len-2]-'0'; + v3=input_string[len-1]-'0'; + return v1*100+v2*10+v3; +} +char* charToString(char ch) +{ + //这里必须设置为静态变量,否则局部变量会被销毁 + static char temp_str[2]; + temp_str[0] = ch; + temp_str[1] = '\0'; + return temp_str; +} +char* get_id_and_term(int id,int term) +{ + //这里必须设置为静态变量,否则局部变量会被销毁 + static char res[50]=""; + res[0]='\0';//清空字符串 + if(id<10) + { + strcat(res,"0"); + strcat(res,charToString('0'+id)); + } + else + { + strcat(res,charToString('0'+id/10)); + strcat(res,charToString('0'+id%10)); + } + strcat(res,"."); + if(term<10) + { + strcat(res,"00"); + strcat(res,charToString('0'+term)); + } + else if(term<100) + { + strcat(res,"0"); + strcat(res,charToString('0'+term/10)); + strcat(res,charToString('0'+term%10)); + } + else + { + strcat(res,charToString('0'+term/100)); + strcat(res,charToString('0'+term%100/10)); + strcat(res,charToString('0'+term%10)); + } + return res; +} + +struct Campaign_Msg_List +{ + //舍弃第[0]个空间,从第[1]个空间开始存数据 + int L,R; + int id[500],term[500]; +}list={1,0}; + +struct Ballot_Set +{ + int len; + int ballot_status[110]; + +}set={node_total_number}; + +void list_append(char *str) +{ + list.R++; + list.id[list.R]=str_identifier(str); + list.term[list.R]=str_term(str); +} +void list_pop_front() +{ + list.L++; +} +int list_get_id() +{ + return list.id[list.L]; +} +int list_get_term() +{ + return list.term[list.L]; +} +int list_size() +{ + return list.R-list.L+1; +} + +void set_clear() +{ + for(int i=0;i<=105;i++) + set.ballot_status[i]=0; +} +int set_count() +{ + int cnt=0; + for(int i=0;i<=105;i++) + if(set.ballot_status[i]==1) + cnt++; + return cnt; +} +void set_add(int x) +{ + set.ballot_status[x]=1; +} +void set_remove(int x) +{ + set.ballot_status[x]=0; +} + +int rand_int(int L,int R) +{ + int x=rand()%(R-L+1); + x=x+L; + return x; +} + + +//void receive_msg(int local_ip,int local_port) +void receive_msg(int local_id) +{ + char *local_ip=IP_address(local_id); + int local_port=PORT(local_id); + Test_TCP_MessageReceive(local_ip,local_port); + //将buffer中的值赋值给receive_string + char *receive_string;//将消息收到的字符串存到这个指针指向的位置 + printf("Received string:%s\n", received_string); + if( strncmp(str_type(received_string),"HeartBeat") ) + { + HeartBeat_received=1; + int HeartBeat_term=str_term(received_string); + //旧leader看到新leader自动退位 + if(my_state==2 && my_term0) + { + while(list_size()) + { + int campaign_id=list_get_id(); + int campaign_term=list_get_term(); + list_pop_front(); + if(my_state==0) + { + if(campaign_term>=my_term+1) + { + my_term=campaign_term + dst_id=campaign_idl + char* str_info=get_id_and_term(my_node_identifier,my_term); + char* sending_msg="give you a vote, I am "; + strcat(sending_msg,str_info); + send_msg(sending_msg,i); + return 1; + } + } + else if(my_state==1) + { + if(campaign_term>=my_term+1) + my_state=0; + my_term=campaign_term; + return 2; + } + } + } + return 0; +} + + +int check_HeartBeat() +{ + if(HeartBeat_received==1) + { + HeartBeat_received=0; + return 1; + } + if(vote_for_candidate()==1) + return 1; + return 0; +} + + +void run_follower() +{ + int T1,T2,timeout_ms,run_time_ms; + timeout_ms=rand_int(4000,8000); + T1=clock(); + while(1) + { + if(check_HeartBeat()) + T1=clock(); + else + { + T2=clock(); + run_time_ms=T2-T1; + if(run_time_msnode_total_number/2) + { + my_state=2; + my_leader=my_node_identifier; + leader_term=my_term; + return; + } + T2=clock(); + run_time_ms=T2-T1; + if(run_time_ms>timeout_ms) + { + my_state=0; + return; + } + } +} + +void run_leader() +{ + while(1) + { + if(my_state==0) + return; + for(int i=1;i<=node_total_number) + { + if(i==my_node_identifier) + continue; + char* str_info=get_id_and_term(my_node_identifier,my_term); + char* sending_msg="HeartBeat, I am "; + strcat(sending_msg,str_info); + send_msg(sending_msg,i); + } + osDelay(200);//我也不知道单位是ms还是s,先认为是ms,以及要注意引入头文件 + } +} + + + + +void raft_kernel() +{ + while(1) + { + print("my_state:%s",charToString('0'+my_state)); + if(my_state==0) + run_follower(); + else if(my_state==1) + run_candidate(); + else if(my_state==2) + run_leader(); + } +} + + + + + + +void Thread_Management(void) +{ + osThreadAttr_t attr1; + + attr1.name = "BasicControl"; + attr1.attr_bits = 0U; + attr1.cb_mem = NULL; + attr1.cb_size = 0U; + attr1.stack_mem = NULL; + attr1.stack_size = 10240; + attr1.priority = 25; + + if (osThreadNew(Task_BasicControl, NULL, &attr1) == NULL) printf("Error:failed to create BasicControl!\n"); + + + osThreadAttr_t attr2; + + attr2.name = "NetDemoTask"; + attr2.attr_bits = 0U; + attr2.cb_mem = NULL; + attr2.cb_size = 0U; + attr2.stack_mem = NULL; + attr2.stack_size = 10240; /* 堆栈大小为10240 */ + attr2.priority = 24; + + if (osThreadNew(Task_NetConnection, NULL, &attr2) == NULL) printf("Error: failed to create NetConnection\n"); +} +APP_FEATURE_INIT(Thread_Management); \ No newline at end of file diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_02.py b/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_02.py new file mode 100644 index 0000000000000000000000000000000000000000..3f50ad77929643af861eca2bd08aa351ffc59dd2 --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_02.py @@ -0,0 +1,274 @@ +import random +import time +from concurrent.futures import ThreadPoolExecutor +from flask import Flask, request +import requests +import threading + +node_total_number=3 +port_car_01=5001 +port_car_02=5002 +port_car_03=5003 + +my_node_identifier=2 + +my_state=0 +my_term=1 +my_leader=-1 +leader_term=-1 + + +HeartBeat_received=False +campaign_msg_list=[] #收到的竞选节点列表,存的是参加竞选的节点的编号,用列表存储是因为需要关注节点的顺序 +ballot_set=set() #follower给自己的投票,存的是投票节点的编号 + +class str_parse: + def type(self,msg): + if(msg[0:9]=='HeartBeat'): + return 'HeartBeat' + elif(msg[0:14]=='give me a vote'): + return 'give me a vote' + elif(msg[0:15]=='give you a vote'): + return 'give you a vote' + else: + return 'not a standard message' + def identifier(self,msg): + t=msg[-6:-4] + return int(t) + def term(self,msg): + t=msg[-3:] + return int(t) + def get_id_and_term(self,id, term): + if (id < 10): + str_node_identifier = "0" + str(id) + else: + str_node_identifier = str(id) + if (term < 10): + str_term = '00' + str(term) + elif (term < 100): + str_term = '0' + str(term) + else: + str_term = str(term) + return str_node_identifier+"."+str_term + + +app = Flask(__name__) + +def receive_msg(): + strp=str_parse() + while True: + # 这里可以编写接收字符串的逻辑 + # 例如,可以使用 Flask 的路由和装饰器来定义字符串的处理函数 + @app.route('/receive', methods=['POST']) + def handle_string(): + global leader_term + global my_leader + global my_state + global my_term + global HeartBeat_received + global ballot_set + + received_string = request.form.get('string') + # 处理接收到的字符串 + print("Received string:", received_string) + if(strp.type(received_string)=='HeartBeat'): + HeartBeat_received = True + HearBeat_term=strp.term(received_string) + #旧leader看到新leader自动退位 + if(my_state==2 and my_term int: + global my_state + global my_term + strp = str_parse() + + if (my_state < 2 and len(campaign_msg_list)): + while (len(campaign_msg_list)): + item = campaign_msg_list[0] + campaign_msg_list.pop(0) + campaign_id = item[0] + campaign_term = item[1] + # candidate的term+1在实现上是先发消息,后+1,因此下面的判断是二者任期相等 + # follower收到第一个任期与自己相等的candidate的消息就会term+1 + # 通过任期判断保证follower只给其中一个candidate投票 + if(my_state==0): + #一定是投票才会更新自己的任期(通常是+1),而每个节点在一个任期内不会重复投票 + #节点在同一个任期内不重复投票通过判断任期来限制 + if (campaign_term>=my_term+1): + my_term = campaign_term + dst_port = 5000 + campaign_id + str_info = strp.get_id_and_term(my_node_identifier, my_term) + sending_msg = "give you a vote, I am " + str_info + send_msg(sending_msg, dst_port) + return 1 + #candidate给自己投票,但仍然需要处理遇到更高任期的candidate的情况 + elif(my_state==1): + if(campaign_term>=my_term+1): + my_state=0 + my_term=campaign_term + return 2 + # 这样实现也不是不行,就是return太慢了,可能会导致candidate有点多,震荡更久 + return 0 + + + + +#检查来自leader的心跳,candidate的竞选投票也被视作心跳 +#设定一个存储空间,来存心跳,如果存储空间中有心跳则清空心跳并返回True,否则返回False +#同时还要处理投票消息并投票 +def check_HeartBeat() -> bool: + #print('T1') + global my_term + global HeartBeat_received + if(HeartBeat_received==True): + HeartBeat_received=False + return True + if(vote_for_candidate()==1): + return True + return False + + +class raft: + def follower(self): + global my_state + global my_term + + + timeout_ms = random.randint(4000, 8000) + + + T1 = time.time() #计时开始 + + while(True): + #只有收到心跳就会重置timeout,无论心跳来自leader还是来自candidate + if(check_HeartBeat()): + T1 = time.time() #重新开始计时 + else: + T2 = time.time() + run_time_ms=(T2-T1)*1000 + if(run_time_ms>timeout_ms): + my_state=1 + return + + def candidate(self): + global my_state + global my_term + global my_leader + global leader_term + global HeartBeat_received + global ballot_set + + + my_term=my_term+1 + + strp = str_parse() + ballot_set = set() + timeout_ms = random.randint(1500, 3000) + T1 = time.time() # 计时开始 + + while(True): + #接收消息的线程看到有新leader出现就会改动my_state + if(my_state==0): + return + # 尽量让candidate给第一个收到竞选消息的节点投票而不是强制给自己投票,这样可以加快共识速度 + # 我看大佬的实现是给自己投票,那我也给自己投票吧,因为candidate给其他candidate投票会涉及任期问题,给自己投票可以避免问题复杂化 + for i in range(1, node_total_number + 1): + if(i==my_node_identifier): + continue + str_info = strp.get_id_and_term(my_node_identifier, my_term) + sending_msg = 'give me a vote, I am ' + str_info + send_msg(sending_msg, 5000 + i) + # 遇到更新任期的节点自动变回follower + if(vote_for_candidate()==2): + if(my_state==0): + return + # 等待一段时间来接收来自节点的投票,并把收到的选票信息放进ballot_set + # code + #print("T3") + if(HeartBeat_received==True): + my_state=0 + HeartBeat_received=False + return + #print("T4") + if( len(ballot_set)+1 > node_total_number / 2 ): + my_state=2 + my_leader=my_node_identifier + leader_term=my_term + return + #print("T5") + T2 = time.time() + run_time_ms = (T2 - T1) * 1000 + #print("T6") + if (run_time_ms > timeout_ms): + my_state = 0 + return + + + # 发送心跳给其他所有节点,包括所有candidate和所有follower,无视来自candidate的选票消息,用心跳回复它即可 + def leader(self): + global my_state + global my_leader + sending_period=200 + while(True): + # 接收消息的线程看到有新leader出现,就会改动my_term + if (my_state==0): + return + for i in range(1,node_total_number+1): + if i==my_node_identifier: + continue + strp=str_parse() + str_info=strp.get_id_and_term(my_node_identifier,my_term) + sending_msg="HeartBeat, I am "+str_info + send_msg(sending_msg,5000+i) + threading.Event().wait(sending_period/1000) + + +def run_raft(): + raft_instance=raft() + while(True): + print("my_state:" + str(my_state)) + if(my_state==0): + raft_instance.follower() + elif(my_state==1): + raft_instance.candidate() + elif(my_state==2): + raft_instance.leader() + else: + print("state error") + break + + +if __name__=='__main__': + # 创建线程池 + with ThreadPoolExecutor(max_workers=2) as executor: + # 提交接收字符串的任务给线程池 + executor.submit(receive_msg) + # 提交发送字符串的任务给线程池 + executor.submit(run_raft) diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_03.c b/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_03.c new file mode 100644 index 0000000000000000000000000000000000000000..9fa9a7492e454c3796d84a895cb2d52687d3724b --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_03.c @@ -0,0 +1,454 @@ +#include +#include +#include +#include + +#ifndef NET_PARAMS_H +#define NET_PARAMS_H + +#ifndef PARAM_HOTSPOT_SSID +#define PARAM_HOTSPOT_SSID "hispark" // your AP SSID +#endif + +#ifndef PARAM_HOTSPOT_PSK +#define PARAM_HOTSPOT_PSK "12345678" // your AP PSK +#endif + +#ifndef PARAM_HOTSPOT_TYPE +#define PARAM_HOTSPOT_TYPE WIFI_SEC_TYPE_PSK // defined in wifi_device_config.h +#endif + +#ifndef PARAM_SERVER_ADDR1 +#define PARAM_SERVER_ADDR1 "192.168.137.137" // server_1 IP address +#endif + +#ifndef PARAM_SERVER_PORT1 +#define PARAM_SERVER_PORT1 5001 // server_1 port +#endif + +#ifndef PARAM_SERVER_ADDR2 +#define PARAM_SERVER_ADDR2 "192.168.137.137" // server_2 IP address +#endif + +#ifndef PARAM_SERVER_PORT2 +#define PARAM_SERVER_PORT2 5002 // server_2 port +#endif + +#ifndef PARAM_SERVER_ADDR3 +#define PARAM_SERVER_ADDR3 "192.168.137.137" // server_2 IP address +#endif + +#ifndef PARAM_SERVER_PORT3 +#define PARAM_SERVER_PORT3 5003 // server_2 port +#endif + +#endif // NET_PARAMS_H + + +char* IP_address(int x) +{ + if(x==1) + return PARAM_SERVER_ADDR1; + else if(x==2) + return PARAM_SERVER_ADDR2; + else if(x==3) + return PARAM_SERVER_ADDR3; +} +unsigned short PORT(int x) +{ + if(x==1) + return PARAM_SERVER_PORT1; + else if(x==2) + return PARAM_SERVER_PORT2; + else if(x==3) + return PARAM_SERVER_PORT3; +} + + + +const int node_total_number=3;//将其设为常量,以至于可以给结构体初始化 + +int port_car_01=5001; +int port_car_02=5002; +int port_car_03=5003; + +int my_node_identifier=3; + +int my_state=0; +int my_term=1; +int my_leader=-1; +int leader_term=-1; + +int HeartBeat_received=0; + + + +char* str_type(char* input_string) +{ + char *t1="HeartBeat"; + char *t2="give me a vote"; + char *t3="give you a vote"; + char *t4="not a standard message"; + if(strncmp(input_string,t1,9)==0) + return t1; + else if(strncmp(input_string,t2,14)==0) + return t2; + else if(strncmp(input_string,t3,15)==0) + return t3; + return t4; +} +int str_identifier(char* input_string) +{ + int len=strlen(input_string); + int v1,v2; + v1=input_string[len-6]-'0'; + v2=input_string[len-5]-'0'; + return v1*10+v2; +} +int str_term(char* input_string) +{ + int len=strlen(input_string); + int v1,v2,v3; + v1=input_string[len-3]-'0'; + v2=input_string[len-2]-'0'; + v3=input_string[len-1]-'0'; + return v1*100+v2*10+v3; +} +char* charToString(char ch) +{ + //这里必须设置为静态变量,否则局部变量会被销毁 + static char temp_str[2]; + temp_str[0] = ch; + temp_str[1] = '\0'; + return temp_str; +} +char* get_id_and_term(int id,int term) +{ + //这里必须设置为静态变量,否则局部变量会被销毁 + static char res[50]=""; + res[0]='\0';//清空字符串 + if(id<10) + { + strcat(res,"0"); + strcat(res,charToString('0'+id)); + } + else + { + strcat(res,charToString('0'+id/10)); + strcat(res,charToString('0'+id%10)); + } + strcat(res,"."); + if(term<10) + { + strcat(res,"00"); + strcat(res,charToString('0'+term)); + } + else if(term<100) + { + strcat(res,"0"); + strcat(res,charToString('0'+term/10)); + strcat(res,charToString('0'+term%10)); + } + else + { + strcat(res,charToString('0'+term/100)); + strcat(res,charToString('0'+term%100/10)); + strcat(res,charToString('0'+term%10)); + } + return res; +} + +struct Campaign_Msg_List +{ + //舍弃第[0]个空间,从第[1]个空间开始存数据 + int L,R; + int id[500],term[500]; +}list={1,0}; + +struct Ballot_Set +{ + int len; + int ballot_status[110]; + +}set={node_total_number}; + +void list_append(char *str) +{ + list.R++; + list.id[list.R]=str_identifier(str); + list.term[list.R]=str_term(str); +} +void list_pop_front() +{ + list.L++; +} +int list_get_id() +{ + return list.id[list.L]; +} +int list_get_term() +{ + return list.term[list.L]; +} +int list_size() +{ + return list.R-list.L+1; +} + +void set_clear() +{ + for(int i=0;i<=105;i++) + set.ballot_status[i]=0; +} +int set_count() +{ + int cnt=0; + for(int i=0;i<=105;i++) + if(set.ballot_status[i]==1) + cnt++; + return cnt; +} +void set_add(int x) +{ + set.ballot_status[x]=1; +} +void set_remove(int x) +{ + set.ballot_status[x]=0; +} + +int rand_int(int L,int R) +{ + int x=rand()%(R-L+1); + x=x+L; + return x; +} + + +//void receive_msg(int local_ip,int local_port) +void receive_msg(int local_id) +{ + char *local_ip=IP_address(local_id); + int local_port=PORT(local_id); + Test_TCP_MessageReceive(local_ip,local_port); + //将buffer中的值赋值给receive_string + char *receive_string;//将消息收到的字符串存到这个指针指向的位置 + printf("Received string:%s\n", received_string); + if( strncmp(str_type(received_string),"HeartBeat") ) + { + HeartBeat_received=1; + int HeartBeat_term=str_term(received_string); + //旧leader看到新leader自动退位 + if(my_state==2 && my_term0) + { + while(list_size()) + { + int campaign_id=list_get_id(); + int campaign_term=list_get_term(); + list_pop_front(); + if(my_state==0) + { + if(campaign_term>=my_term+1) + { + my_term=campaign_term + dst_id=campaign_idl + char* str_info=get_id_and_term(my_node_identifier,my_term); + char* sending_msg="give you a vote, I am "; + strcat(sending_msg,str_info); + send_msg(sending_msg,i); + return 1; + } + } + else if(my_state==1) + { + if(campaign_term>=my_term+1) + my_state=0; + my_term=campaign_term; + return 2; + } + } + } + return 0; +} + + +int check_HeartBeat() +{ + if(HeartBeat_received==1) + { + HeartBeat_received=0; + return 1; + } + if(vote_for_candidate()==1) + return 1; + return 0; +} + + +void run_follower() +{ + int T1,T2,timeout_ms,run_time_ms; + timeout_ms=rand_int(4000,8000); + T1=clock(); + while(1) + { + if(check_HeartBeat()) + T1=clock(); + else + { + T2=clock(); + run_time_ms=T2-T1; + if(run_time_msnode_total_number/2) + { + my_state=2; + my_leader=my_node_identifier; + leader_term=my_term; + return; + } + T2=clock(); + run_time_ms=T2-T1; + if(run_time_ms>timeout_ms) + { + my_state=0; + return; + } + } +} + +void run_leader() +{ + while(1) + { + if(my_state==0) + return; + for(int i=1;i<=node_total_number) + { + if(i==my_node_identifier) + continue; + char* str_info=get_id_and_term(my_node_identifier,my_term); + char* sending_msg="HeartBeat, I am "; + strcat(sending_msg,str_info); + send_msg(sending_msg,i); + } + osDelay(200);//我也不知道单位是ms还是s,先认为是ms,以及要注意引入头文件 + } +} + + + + +void raft_kernel() +{ + while(1) + { + print("my_state:%s",charToString('0'+my_state)); + if(my_state==0) + run_follower(); + else if(my_state==1) + run_candidate(); + else if(my_state==2) + run_leader(); + } +} + + + + + + +void Thread_Management(void) +{ + osThreadAttr_t attr1; + + attr1.name = "BasicControl"; + attr1.attr_bits = 0U; + attr1.cb_mem = NULL; + attr1.cb_size = 0U; + attr1.stack_mem = NULL; + attr1.stack_size = 10240; + attr1.priority = 25; + + if (osThreadNew(Task_BasicControl, NULL, &attr1) == NULL) printf("Error:failed to create BasicControl!\n"); + + + osThreadAttr_t attr2; + + attr2.name = "NetDemoTask"; + attr2.attr_bits = 0U; + attr2.cb_mem = NULL; + attr2.cb_size = 0U; + attr2.stack_mem = NULL; + attr2.stack_size = 10240; /* 堆栈大小为10240 */ + attr2.priority = 24; + + if (osThreadNew(Task_NetConnection, NULL, &attr2) == NULL) printf("Error: failed to create NetConnection\n"); +} +APP_FEATURE_INIT(Thread_Management); \ No newline at end of file diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_03.py b/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_03.py new file mode 100644 index 0000000000000000000000000000000000000000..021301dd242920454aa44b528a08eb83d244917f --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/car_03.py @@ -0,0 +1,274 @@ +import random +import time +from concurrent.futures import ThreadPoolExecutor +from flask import Flask, request +import requests +import threading + +node_total_number=3 +port_car_01=5001 +port_car_02=5002 +port_car_03=5003 + +my_node_identifier=3 + +my_state=0 +my_term=1 +my_leader=-1 +leader_term=-1 + + +HeartBeat_received=False +campaign_msg_list=[] #收到的竞选节点列表,存的是参加竞选的节点的编号,用列表存储是因为需要关注节点的顺序 +ballot_set=set() #follower给自己的投票,存的是投票节点的编号 + +class str_parse: + def type(self,msg): + if(msg[0:9]=='HeartBeat'): + return 'HeartBeat' + elif(msg[0:14]=='give me a vote'): + return 'give me a vote' + elif(msg[0:15]=='give you a vote'): + return 'give you a vote' + else: + return 'not a standard message' + def identifier(self,msg): + t=msg[-6:-4] + return int(t) + def term(self,msg): + t=msg[-3:] + return int(t) + def get_id_and_term(self,id, term): + if (id < 10): + str_node_identifier = "0" + str(id) + else: + str_node_identifier = str(id) + if (term < 10): + str_term = '00' + str(term) + elif (term < 100): + str_term = '0' + str(term) + else: + str_term = str(term) + return str_node_identifier+"."+str_term + + +app = Flask(__name__) + +def receive_msg(): + strp=str_parse() + while True: + # 这里可以编写接收字符串的逻辑 + # 例如,可以使用 Flask 的路由和装饰器来定义字符串的处理函数 + @app.route('/receive', methods=['POST']) + def handle_string(): + global leader_term + global my_leader + global my_state + global my_term + global HeartBeat_received + global ballot_set + + received_string = request.form.get('string') + # 处理接收到的字符串 + print("Received string:", received_string) + if(strp.type(received_string)=='HeartBeat'): + HeartBeat_received = True + HearBeat_term=strp.term(received_string) + #旧leader看到新leader自动退位 + if(my_state==2 and my_term int: + global my_state + global my_term + strp = str_parse() + + if (my_state < 2 and len(campaign_msg_list)): + while (len(campaign_msg_list)): + item = campaign_msg_list[0] + campaign_msg_list.pop(0) + campaign_id = item[0] + campaign_term = item[1] + # candidate的term+1在实现上是先发消息,后+1,因此下面的判断是二者任期相等 + # follower收到第一个任期与自己相等的candidate的消息就会term+1 + # 通过任期判断保证follower只给其中一个candidate投票 + if(my_state==0): + #一定是投票才会更新自己的任期(通常是+1),而每个节点在一个任期内不会重复投票 + #节点在同一个任期内不重复投票通过判断任期来限制 + if (campaign_term>=my_term+1): + my_term = campaign_term + dst_port = 5000 + campaign_id + str_info = strp.get_id_and_term(my_node_identifier, my_term) + sending_msg = "give you a vote, I am " + str_info + send_msg(sending_msg, dst_port) + return 1 + #candidate给自己投票,但仍然需要处理遇到更高任期的candidate的情况 + elif(my_state==1): + if(campaign_term>=my_term+1): + my_state=0 + my_term=campaign_term + return 2 + # 这样实现也不是不行,就是return太慢了,可能会导致candidate有点多,震荡更久 + return 0 + + + + +#检查来自leader的心跳,candidate的竞选投票也被视作心跳 +#设定一个存储空间,来存心跳,如果存储空间中有心跳则清空心跳并返回True,否则返回False +#同时还要处理投票消息并投票 +def check_HeartBeat() -> bool: + #print('T1') + global my_term + global HeartBeat_received + if(HeartBeat_received==True): + HeartBeat_received=False + return True + if(vote_for_candidate()==1): + return True + return False + + +class raft: + def follower(self): + global my_state + global my_term + + + timeout_ms = random.randint(4000, 8000) + + + T1 = time.time() #计时开始 + + while(True): + #只有收到心跳就会重置timeout,无论心跳来自leader还是来自candidate + if(check_HeartBeat()): + T1 = time.time() #重新开始计时 + else: + T2 = time.time() + run_time_ms=(T2-T1)*1000 + if(run_time_ms>timeout_ms): + my_state=1 + return + + def candidate(self): + global my_state + global my_term + global my_leader + global leader_term + global HeartBeat_received + global ballot_set + + + my_term=my_term+1 + + strp = str_parse() + ballot_set = set() + timeout_ms = random.randint(1500, 3000) + T1 = time.time() # 计时开始 + + while(True): + #接收消息的线程看到有新leader出现就会改动my_state + if(my_state==0): + return + # 尽量让candidate给第一个收到竞选消息的节点投票而不是强制给自己投票,这样可以加快共识速度 + # 我看大佬的实现是给自己投票,那我也给自己投票吧,因为candidate给其他candidate投票会涉及任期问题,给自己投票可以避免问题复杂化 + for i in range(1, node_total_number + 1): + if(i==my_node_identifier): + continue + str_info = strp.get_id_and_term(my_node_identifier, my_term) + sending_msg = 'give me a vote, I am ' + str_info + send_msg(sending_msg, 5000 + i) + # 遇到更新任期的节点自动变回follower + if(vote_for_candidate()==2): + if(my_state==0): + return + # 等待一段时间来接收来自节点的投票,并把收到的选票信息放进ballot_set + # code + #print("T3") + if(HeartBeat_received==True): + my_state=0 + HeartBeat_received=False + return + #print("T4") + if( len(ballot_set)+1 > node_total_number / 2 ): + my_state=2 + my_leader=my_node_identifier + leader_term=my_term + return + #print("T5") + T2 = time.time() + run_time_ms = (T2 - T1) * 1000 + #print("T6") + if (run_time_ms > timeout_ms): + my_state = 0 + return + + + # 发送心跳给其他所有节点,包括所有candidate和所有follower,无视来自candidate的选票消息,用心跳回复它即可 + def leader(self): + global my_state + global my_leader + sending_period=200 + while(True): + # 接收消息的线程看到有新leader出现,就会改动my_term + if (my_state==0): + return + for i in range(1,node_total_number+1): + if i==my_node_identifier: + continue + strp=str_parse() + str_info=strp.get_id_and_term(my_node_identifier,my_term) + sending_msg="HeartBeat, I am "+str_info + send_msg(sending_msg,5000+i) + threading.Event().wait(sending_period/1000) + + +def run_raft(): + raft_instance=raft() + while(True): + print("my_state:" + str(my_state)) + if(my_state==0): + raft_instance.follower() + elif(my_state==1): + raft_instance.candidate() + elif(my_state==2): + raft_instance.leader() + else: + print("state error") + break + + +if __name__=='__main__': + # 创建线程池 + with ThreadPoolExecutor(max_workers=2) as executor: + # 提交接收字符串的任务给线程池 + executor.submit(receive_msg) + # 提交发送字符串的任务给线程池 + executor.submit(run_raft) diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/communication_receive.c b/AIOT/12182_Intelligent cooperative parking system for fleet/project/communication_receive.c new file mode 100644 index 0000000000000000000000000000000000000000..fe9f20eeef94702cb5abefe09bd0859c55ee04c9 --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/communication_receive.c @@ -0,0 +1,7 @@ +#include +#include +#include +#include +#include +#include +#include \ No newline at end of file diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/control_Main.c b/AIOT/12182_Intelligent cooperative parking system for fleet/project/control_Main.c new file mode 100644 index 0000000000000000000000000000000000000000..7b6c654ef2e1116978651a43b518139f6c83f128 --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/control_Main.c @@ -0,0 +1,288 @@ +#include +#include +#include + +#include "ohos_init.h" +#include "cmsis_os2.h" +#include "iot_gpio.h" +#include "hi_io.h" +#include "hi_time.h" +#include "control_Main.h" +#include "hi_adc.h" +#include "iot_errno.h" + +#define GPIO5 5 // GPIO5 is connected to a switch +#define ADC_TEST_LENGTH (20) +#define VLT_MIN (100) +#define OLED_FALG_ON ((unsigned char)0x01) +#define OLED_FALG_OFF ((unsigned char)0x00) + +unsigned short g_adc_buf[ADC_TEST_LENGTH] = {0}; +unsigned short g_gpio5_adc_buf[ADC_TEST_LENGTH] = {0}; +unsigned int g_gpio5_tick = 0; +unsigned char g_car_control_mode = 0; +unsigned char g_car_speed_control = 0; +unsigned int g_car_control_demo_task_id = 0; +unsigned char g_car_status = CAR_STOP_STATUS; + +// Ultrasonic Ranging +extern float HCSR04_distance_get(int); + +// Following the Trace +extern void Trace_Follow(void); + +// Basic movements +extern void TurnLeft(void); +extern void TurnRight(void); +extern void GoForward(void); +extern void GoBack(void); +extern void CarStop(void); + +// trigger two motors +extern void RunMotor(void); + +//Receive Message from another car +extern void Task_NetConnection(void); + +void switch_init(void) +{ + IoTGpioInit(5); + hi_io_set_func(5, 0); + IoTGpioSetDir(5, 0); // input + hi_io_set_pull(5, 1); +} + +void gpio5_isr_func_mode(void) +{ + printf("gpio5_isr_func_mode start\n"); + unsigned int tick_interval = 0; + unsigned int current_gpio5_tick = 0; + + current_gpio5_tick = hi_get_tick(); // get the current tick + tick_interval = current_gpio5_tick - g_gpio5_tick; // claculate the interval + + if (tick_interval < KEY_INTERRUPT_PROTECT_TIME) + { + return NULL; + } + g_gpio5_tick = current_gpio5_tick; //update the value of tick + + if (g_car_status == CAR_STOP_STATUS) + { + g_car_status = CAR_TRACE_STATUS; //follow the trace + printf("trace\n"); + } + else if (g_car_status == CAR_TRACE_STATUS) + { + g_car_status = CAR_OBSTACLE_AVOIDANCE_STATUS; //ultrasonic ranging and avoid obstacle + printf("ultrasonic\n"); + } + else if (g_car_status == CAR_OBSTACLE_AVOIDANCE_STATUS) + { + g_car_status = CAR_STOP_STATUS; // 停止 + printf("stop\n"); + } +} + +unsigned char get_gpio5_voltage(void *param) +{ + int i; + unsigned short data; + unsigned int ret; + unsigned short vlt; + float voltage; + float vlt_max = 0; + float vlt_min = VLT_MIN; + + hi_unref_param(param); + memset_s(g_gpio5_adc_buf, sizeof(g_gpio5_adc_buf), 0x0, sizeof(g_gpio5_adc_buf)); + for (i = 0; i < ADC_TEST_LENGTH; i++) + { + ret = hi_adc_read(HI_ADC_CHANNEL_2, &data, HI_ADC_EQU_MODEL_4, HI_ADC_CUR_BAIS_DEFAULT, 0xF0); + // ADC_Channal_2 自动识别模式 CNcomment:4次平均算法模式 CNend */ + if (ret != IOT_SUCCESS) + { + printf("ADC Read Fail\n"); + return NULL; + } + g_gpio5_adc_buf[i] = data; + } + + for (i = 0; i < ADC_TEST_LENGTH; i++) + { + vlt = g_gpio5_adc_buf[i]; + voltage = (float)vlt * 1.8 * 4 / 4096.0; + /* vlt * 1.8* 4 / 4096.0为将码字转换为电压 */ + vlt_max = (voltage > vlt_max) ? voltage : vlt_max; + vlt_min = (voltage < vlt_min) ? voltage : vlt_min; + } + printf("vlt_max is %f\r\n", vlt_max); + if (vlt_max > 0.6 && vlt_max < 1.0) + { + gpio5_isr_func_mode(); + } +} + +// 按键中断 +void interrupt_monitor(void) +{ + unsigned int ret = 0; + /*gpio5 switch2 mode*/ + g_gpio5_tick = hi_get_tick(); + ret = IoTGpioRegisterIsrFunc(GPIO5, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW, get_gpio5_voltage, NULL); + if (ret == IOT_SUCCESS) + { + printf(" register gpio5\r\n"); + } +} + +/*Judge steering gear*/ +static unsigned int engine_go_where(void) +{ + float left_distance = 0; + float right_distance = 0; + + //measure the left distance + left_distance = HCSR04_distance_get(-90); + hi_sleep(100); + + /*regress*/ + HCSR04_distance_get(0); + + //measure the right distance + left_distance = HCSR04_distance_get(90); + hi_sleep(100); + + //regress + HCSR04_distance_get(0); + if (left_distance > right_distance) + { + return CAR_TURN_LEFT; + } + else + { + return CAR_TURN_RIGHT; + } +} + +/*Judge the direction of the car*/ +static void car_where_to_go(float distance) +{ + if (distance < DISTANCE_BETWEEN_CAR_AND_OBSTACLE) + { + CarStop(); + RunMotor(); + hi_sleep(500); + GoBack(); + RunMotor; + hi_sleep(500); + CarStop(); + RunMotor(); + unsigned int ret = engine_go_where(); + printf("ret is %d\r\n", ret); + if (ret == CAR_TURN_LEFT) + { + TurnLeft(); + RunMotor(); + hi_sleep(500); + } + else if (ret == CAR_TURN_RIGHT) + { + TurnRight(); + RunMotor(); + hi_sleep(500); + } + CarStop(); + RunMotor(); + } + else + { + GoForward(); + RunMotor(); + } +} + +/*car mode control func*/ +static void car_mode_control_func(void) +{ + float m_distance = 0.0; + regress_middle(); + while (1) + { + if (g_car_status != CAR_OBSTACLE_AVOIDANCE_STATUS) + { + printf("car_mode_control_func 1 module changed\n"); + regress_middle(); + break; + } + + //measure the distance + m_distance = GetDistance(); + printf("m_distance = %f\n",m_distance); + car_where_to_go(m_distance); + hi_sleep(20); + } +} + +void *Task_BasicControl(void *param) +{ + printf("switch\r\n"); + switch_init(); + interrupt_monitor(); + + while (1) + { + switch (g_car_status) + { + case CAR_STOP_STATUS: + CarStop(); + RunMotor(); + break; + case CAR_OBSTACLE_AVOIDANCE_STATUS: + car_mode_control_func(); + break; + case CAR_TRACE_STATUS: + Trace_Follow(); + break; + default: + break; + } + IoTWatchDogDisable(); + osDelay(20); + } +} + +void *Task_Receive(void *param) +{ + +} + + +void Thread_Management(void) +{ + osThreadAttr_t attr1; + + attr1.name = "BasicControl"; + attr1.attr_bits = 0U; + attr1.cb_mem = NULL; + attr1.cb_size = 0U; + attr1.stack_mem = NULL; + attr1.stack_size = 10240; + attr1.priority = 25; + + if (osThreadNew(Task_BasicControl, NULL, &attr1) == NULL) printf("Error:failed to create BasicControl!\n"); + + + osThreadAttr_t attr2; + + attr2.name = "NetDemoTask"; + attr2.attr_bits = 0U; + attr2.cb_mem = NULL; + attr2.cb_size = 0U; + attr2.stack_mem = NULL; + attr2.stack_size = 10240; /* 堆栈大小为10240 */ + attr2.priority = 24; + + if (osThreadNew(Task_NetConnection, NULL, &attr2) == NULL) printf("Error: failed to create NetConnection\n"); +} +APP_FEATURE_INIT(Thread_Management); \ No newline at end of file diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/control_Main.h b/AIOT/12182_Intelligent cooperative parking system for fleet/project/control_Main.h new file mode 100644 index 0000000000000000000000000000000000000000..0d25f90d6def6ed9865f4f4973f5108aba47d607 --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/control_Main.h @@ -0,0 +1,20 @@ +#ifndef __APP_DEMO_ROBOT_CAR_H__ +#define __APP_DEMO_ROBOT_CAR_H__ + + +#define CAR_CONTROL_DEMO_TASK_STAK_SIZE (1024*10) +#define CAR_CONTROL_DEMO_TASK_PRIORITY (25) +#define DISTANCE_BETWEEN_CAR_AND_OBSTACLE (20) +#define KEY_INTERRUPT_PROTECT_TIME (30) +#define CAR_TURN_LEFT (0) +#define CAR_TURN_RIGHT (1) + +typedef enum { + CAR_STOP_STATUS = 0, + CAR_OBSTACLE_AVOIDANCE_STATUS, + CAR_TRACE_STATUS +} CarStatus; + +void switch_init(void); +void interrupt_monitor(void); +#endif \ No newline at end of file diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/control_TraceFollow.c b/AIOT/12182_Intelligent cooperative parking system for fleet/project/control_TraceFollow.c new file mode 100644 index 0000000000000000000000000000000000000000..c2149351a3e126e95e85e4c893ea6480d08f814e --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/control_TraceFollow.c @@ -0,0 +1,138 @@ +#include "ohos_init.h" +#include "cmsis_os2.h" +#include "iot_gpio.h" +#include "hi_io.h" +#include "hi_time.h" +#include "iot_watchdog.h" +#include "robot_control.h" +#include "iot_errno.h" +#include "hi_pwm.h" +#include "hi_timer.h" +#include "iot_pwm.h" + +#define GPIO0 0 // GPIO0 is connected to the left_reverse +#define GPIO1 1 // GPIO1 is connected to the left_forward +#define GPIO9 9 // GPIO9 is connected to the right_reverse +#define GPIO10 10 // GPIO10 is connected to the right_forward +#define GPIO11 11 // GPIO11 is connected to the left TCRT5000 module +#define GPIO12 12 // GPIO12 is connected to the right TCRT5000 module + +extern unsigned char g_car_status; + +unsigned int left_reverse = 1; +unsigned int left_forward = 1; +unsigned int right_reverse = 1; +unsigned int right_forward = 1; +IotGpioValue trace_detection; +IotGpioValue trace_detection_left; +IotGpioValue trace_detection_right; + +void TurnLeft(void) +{ + left_reverse = 0; + left_forward = 1; + right_reverse = 1; + right_forward = 0; +} + + + +void TurnRight(void) +{ + left_reverse = 1; + left_forward = 0; + right_reverse = 0; + right_forward = 1; +} + +void GoForward(void) +{ + left_reverse = 0; + left_forward = 1; + right_reverse = 0; + right_forward = 1; +} + +void GoBack(void) +{ + left_reverse = 1; + left_forward = 0; + right_reverse = 1; + right_forward = 0; +} + +void CarStop(void) +{ + left_reverse = 1; + left_forward = 1; + right_reverse = 1; + right_forward = 1; +} + +void RunMotor(void) +{ + gpio_control(GPIO0, left_reverse); + gpio_control(GPIO1, left_forward); + gpio_control(GPIO9, right_reverse); + gpio_control(GPIO10, right_forward); + hi_udelay(20); +} + +void timer1_callback(unsigned int arg) +{ + IoTGpioGetInputVal(GPIO11, &trace_detection); + if (!((left_reverse = 1) && (left_forward = 0))) + { + IoTGpioGetInputVal(GPIO11, &trace_detection); + if (trace_detection == 1) + { + left_reverse = 0; + left_forward = 1; + printf("left forward \r\n"); + } + } + + if (!((right_reverse = 1) && (right_forward = 0))) + { + IoTGpioGetInputVal(GPIO12, &trace_detection); + if (trace_detection == 1) + { + right_reverse = 0; + right_forward = 1; + printf("right forward \r\n"); + } + } + + if ((!((left_reverse = 1) && (left_forward = 0))) && (!((right_reverse = 1) && (right_forward = 0)))) + { + GoForward(); + } + + IoTGpioGetInputVal(GPIO11, &trace_detection_left); + IoTGpioGetInputVal(GPIO12, &trace_detection_right); + if (trace_detection_right == 0 && trace_detection_left == 1) + { + TurnLeft(); + } + if (trace_detection_right == 1 && trace_detection_left == 0) + { + TurnRight(); + } +} + +void Trace_Follow(void) +{ + unsigned int timer1; + hi_timer_create(&timer1); + hi_timer_start(timer1, HI_TIMER_TYPE_PERIOD, 1, timer1_callback, 0); + GoForward(); + RunMotor(); + while (1) { + GoForward(); + RunMotor(); + if (g_car_status != CAR_TRACE_STATUS) { + break; + } + } + hi_timer_delete(timer1); +} \ No newline at end of file diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/control_UltrasonicRanging.c b/AIOT/12182_Intelligent cooperative parking system for fleet/project/control_UltrasonicRanging.c new file mode 100644 index 0000000000000000000000000000000000000000..1d979b8ae16d9c72248ae98e8a37e720b429ab94 --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/control_UltrasonicRanging.c @@ -0,0 +1,68 @@ +#include +#include +#include + +#include "ohos_init.h" +#include "cmsis_os2.h" +#include "iot_gpio.h" +#include "hi_io.h" +#include "hi_time.h" + +#define GPIO2 2 // GPIO2 is connected to the SG90 +#define GPIO_7 7 // GPIO7 is connected to the ultrasonic_Echo +#define GPIO_8 8 // GPIO8 is connected to the ultrasonic_Trig + +//a function used to set the direction of SG90 +void SG90_angle_set(int angle) +{ + for (int i = 0; i < 10; i++) + { + unsigned int duty = 1500 + angle / 0.18; + IoTGpioInit(GPIO2); + IoTGpioSetDir(GPIO2, 1); // output + IoTGpioSetOutputVal(GPIO2, 1); + hi_udelay(duty); + IoTGpioSetOutputVal(GPIO2, 0); + hi_udelay(20000 - duty); + } +} + +//a function used to get the distance in a wanted direction +float HCSR04_distance_get (int angle) { + static unsigned long beginning = 0, time = 0; + float distance = 0.0; + unsigned int Echo = 0; + unsigned int flag = 0; + IoTWatchDogDisable(); + + hi_io_set_func(GPIO_8, 0); + IoTGpioSetDir(GPIO_8, 0); //input + IoTGpioSetDir(GPIO_7, 1); //output + + //turn the ultrasonic sensor to the wanted direction + SG90_angle_set(angle); + hi_sleep(100); + //send signal to trigger the ultrasonic sensor + IoTGpioSetOutputVal(GPIO_7, 1); + hi_udelay(20); + IoTGpioSetOutputVal(GPIO_7, 0); + + //record the time spent during the transmission of ultrasonic + while (1) { + IoTGpioGetInputVal(GPIO_8, &Echo); + if ( Echo == 1 && flag == 0) { + beginning = hi_get_us(); + flag = 1; + } + if (Echo == 1 && flag == 1) { + time = hi_get_us() - beginning; + beginning = 0; + break; + } + } + //calculate the distance + distance = time * 0.034 / 2; + printf("distance is %f\r\n",distance); + return distance; +} + diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/training_code.py b/AIOT/12182_Intelligent cooperative parking system for fleet/project/training_code.py new file mode 100644 index 0000000000000000000000000000000000000000..31761c42931ab778e560e825efd76dc10703197a --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/training_code.py @@ -0,0 +1,107 @@ +import os +import torch +import torch.nn as nn +import torch.optim as optim +import torchvision.transforms as transforms +import torchvision.datasets as datasets +from torch.utils.data import DataLoader + +path_to_train=r'D:\study_study_study_study_study\code\pycharm\CV\sign_recognition\data_set\train_set' +path_to_test=r'D:\study_study_study_study_study\code\pycharm\CV\sign_recognition\data_set\test_set' + + + +# 设定一些超参数 +batch_size = 64 +num_epochs = 10 +learning_rate = 0.001 +num_classes = len(os.listdir(path_to_train)) + +# 定义数据增强和转换 +transform = transforms.Compose([ + transforms.RandomResizedCrop(224), + transforms.RandomHorizontalFlip(), + transforms.ToTensor(), + transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), +]) + +# 加载数据集 +train_dataset = datasets.ImageFolder(root=path_to_train, transform=transform) +train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) + +test_dataset = datasets.ImageFolder(root=path_to_test, transform=transform) +test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False) + +# 定义卷积神经网络模型 +class CNNModel(nn.Module): + def __init__(self, num_classes): + super(CNNModel, self).__init__() + self.features = nn.Sequential( + nn.Conv2d(3, 16, kernel_size=3, padding=1), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=2, stride=2), + nn.Conv2d(16, 32, kernel_size=3, padding=1), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=2, stride=2), + ) + self.classifier = nn.Sequential( + nn.Linear(32 * 56 * 56, 256), + nn.ReLU(inplace=True), + nn.Dropout(0.5), + nn.Linear(256, num_classes), + ) + + def forward(self, x): + x = self.features(x) + x = torch.flatten(x, 1) + x = self.classifier(x) + return x + +# 初始化模型和损失函数,选择优化器 +device = torch.device("cuda" if torch.cuda.is_available() else "cpu") +model = CNNModel(num_classes).to(device) +criterion = nn.CrossEntropyLoss() +optimizer = optim.Adam(model.parameters(), lr=learning_rate) + + + +print("T1") + + +# 训练模型 +total_step = len(train_loader) +for epoch in range(num_epochs): + print("T2") + for i, (images, labels) in enumerate(train_loader): + print("T4") + images = images.to(device) + labels = labels.to(device) + # 前向传播和计算损失 + outputs = model(images) + loss = criterion(outputs, labels) + # 反向传播和优化 + optimizer.zero_grad() + loss.backward() + optimizer.step() + if (i + 1) % 100 == 0: + print(f"Epoch [{epoch + 1}/{num_epochs}], Step [{i + 1}/{total_step}], Loss: {loss.item():.4f}") + +# 在测试集上评估模型 +model.eval() +with torch.no_grad(): + correct = 0 + total = 0 + for images, labels in test_loader: + print("T3") + images = images.to(device) + labels = labels.to(device) + outputs = model(images) + _, predicted = torch.max(outputs.data, 1) + total += labels.size(0) + correct += (predicted == labels).sum().item() + + print("测试集上的准确率: {} %".format(100 * correct / total)) + +# 保存模型 +torch.save(model.state_dict(), "cnn_model.ckpt") +print("模型已保存为 'cnn_model.ckpt'") diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/trashbin/Message_Queue.c b/AIOT/12182_Intelligent cooperative parking system for fleet/project/trashbin/Message_Queue.c new file mode 100644 index 0000000000000000000000000000000000000000..7f96082e1ae8866782cdfbc082a7c6d0f9b0e22f --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/trashbin/Message_Queue.c @@ -0,0 +1,86 @@ +#include +#include +#include + +#include "ohos_init.h" +#include "cmsis_os2.h" + + +#define NUM 1 +#define STACK_SIZE 1024 +#define QUEUE_SIZE 10 +typedef struct { + osThreadId_t thread_id; + int count; + char message_content[50]; +} message_entry; +osMessageQueueId_t queue_id; + +void sender_thread(int *arg) +{ + int count; + message_entry sentry; + (int)arg; + while (NUM) { + + sentry.thread_id = osThreadGetId(); + sentry.count = count; + strcpy(sentry.message_content, ""); + osMessageQueuePut(queue_id, (const int *)&sentry, 0, osWaitForever); + count++; + osDelay(5); + } +} + +void receiver_thread(int *arg) +{ + (int)arg; + message_entry rentry; + while (NUM) { + osMessageQueueGet(queue_id, (int *)&rentry, NULL, osWaitForever); + osThreadGetName(osThreadGetId()), rentry.count, osThreadGetName(rentry.thread_id)); + osDelay(5); + } +} + +osThreadId_t newThread(char *name, osThreadFunc_t func, int *arg) +{ + osThreadAttr_t attr = { + name, 0, NULL, 0, NULL, 1024*2, 24, 0, 0 + }; + osThreadId_t tid = osThreadNew(func, arg, &attr); + if (tid == NULL) { + printf("Error: osThreadNew(%s) failed.\r\n", name); + } else { + printf("Error: osThreadNew(%s) success, thread id: %d.\r\n", name, tid); + } + return tid; +} + +void Create_Message_Queue(int *arg) +{ + (int)arg; + + osMessageQueueNew(QUEUE_SIZE, sizeof(message_entry), NULL); + newThread("receiver1", receiver_thread, NULL); + newThread("sender1", sender_thread, NULL); +} + +static void Thread_MessageQueue(void) +{ + osThreadAttr_t attr4_MessageQueue; + + attr4_MessageQueue.name = "rtosv2_msgq_main"; + attr4_MessageQueue.attr_bits = 0U; + attr4_MessageQueue.cb_mem = NULL; + attr4_MessageQueue.cb_size = 0U; + attr4_MessageQueue.stack_mem = NULL; + attr4_MessageQueue.stack_size = 1024; + attr4_MessageQueue.priority = 24; + + if (osThreadNew((osThreadFunc_t)Create_Message_Queue, NULL, &attr4_MessageQueue) == NULL) { + printf("[MessageTestTask] Failed to create rtosv2_msgq_main!\n"); + } +} + + diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/wifi_connecter.c b/AIOT/12182_Intelligent cooperative parking system for fleet/project/wifi_connecter.c new file mode 100644 index 0000000000000000000000000000000000000000..b6a37e0aa3469c4328db89e41b1b4a35ef7a25fc --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/wifi_connecter.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "wifi_device.h" +#include "cmsis_os2.h" + +#include "lwip/netifapi.h" +#include "lwip/api_shell.h" +#include "net_params.h" + +static void PrintLinkedInfo(WifiLinkedInfo* info) +{ + int ret = 0; + + if (!info) { + return; + } + + static char macAddress[32] = {0}; + unsigned char* mac = info->bssid; + if (snprintf_s(macAddress, sizeof(macAddress) + 1, sizeof(macAddress), "%02X:%02X:%02X:%02X:%02X:%02X", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) < 0) { /* mac地址从0,1,2,3,4,5位 */ + return; + } +} + +static volatile int g_connected = 0; + +static void OnWifiConnectionChanged(int state, WifiLinkedInfo* info) +{ + if (!info) return; + + printf("%s %d, state = %d, info = \r\n", __FUNCTION__, __LINE__, state); + PrintLinkedInfo(info); + + if (state == WIFI_STATE_AVALIABLE) { + g_connected = 1; + } else { + g_connected = 0; + } +} + +static void OnWifiScanStateChanged(int state, int size) +{ + printf("%s %d, state = %X, size = %d\r\n", __FUNCTION__, __LINE__, state, size); +} + +static WifiEvent g_defaultWifiEventListener = { + .OnWifiConnectionChanged = OnWifiConnectionChanged, + .OnWifiScanStateChanged = OnWifiScanStateChanged +}; + +static struct netif* g_iface = NULL; + +err_t netifapi_set_hostname(struct netif *netif, char *hostname, u8_t namelen); +#define SSID_LEN (11) +#define PSK_LEN (9) +int ConnectToHotspot(void) +{ + WifiDeviceConfig config = {0}; + + // 准备AP的配置参数 + strcpy_s(config.ssid, SSID_LEN, PARAM_HOTSPOT_SSID); + strcpy_s(config.preSharedKey, PSK_LEN, PARAM_HOTSPOT_PSK); + config.securityType = PARAM_HOTSPOT_TYPE; + + osDelay(10); /* 延时10ms */ + WifiErrorCode errCode; + int netId = -1; + + errCode = RegisterWifiEvent(&g_defaultWifiEventListener); + printf("RegisterWifiEvent: %d\r\n", errCode); + + errCode = EnableWifi(); + printf("EnableWifi: %d\r\n", errCode); + + errCode = AddDeviceConfig(&config, &netId); + printf("AddDeviceConfig: %d\r\n", errCode); + + g_connected = 0; + errCode = ConnectTo(netId); + printf("ConnectTo(%d): %d\r\n", netId, errCode); + + while (!g_connected) { // wait until connect to AP + osDelay(10); /* 持续10ms去连接AP */ + } + printf("g_connected: %d\r\n", g_connected); + + g_iface = netifapi_netif_find("wlan0"); + if (g_iface) { + char* hostname = "hispark"; + err_t ret = netifapi_set_hostname(g_iface, hostname, strlen(hostname)); + printf("netifapi_set_hostname: %d\r\n", ret); + + ret = netifapi_dhcp_start(g_iface); + printf("netifapi_dhcp_start: %d\r\n", ret); + + osDelay(100); // wait DHCP server give me IP 100 +#if 1 + ret = netifapi_netif_common(g_iface, dhcp_clients_info_show, NULL); + printf("netifapi_netif_common: %d\r\n", ret); +#else +#endif + } + return netId; +} + +void DisconnectWithHotspot(int netId) +{ + if (g_iface) { + err_t ret = netifapi_dhcp_stop(g_iface); + printf("netifapi_dhcp_stop: %d\r\n", ret); + } + + WifiErrorCode errCode = Disconnect(); // disconnect with your AP + printf("Disconnect: %d\r\n", errCode); + + errCode = UnRegisterWifiEvent(&g_defaultWifiEventListener); + printf("UnRegisterWifiEvent: %d\r\n", errCode); + + RemoveDevice(netId); // remove AP config + printf("RemoveDevice: %d\r\n", errCode); + + errCode = DisableWifi(); + printf("DisableWifi: %d\r\n", errCode); +} \ No newline at end of file diff --git a/AIOT/12182_Intelligent cooperative parking system for fleet/project/wifi_connecter.h b/AIOT/12182_Intelligent cooperative parking system for fleet/project/wifi_connecter.h new file mode 100644 index 0000000000000000000000000000000000000000..72c26ea36c6da3ee1cd57cf7e70f353e5e6585b9 --- /dev/null +++ b/AIOT/12182_Intelligent cooperative parking system for fleet/project/wifi_connecter.h @@ -0,0 +1,8 @@ +#ifndef WIFI_CONNECTER_H +#define WIFI_CONNECTER_H + +int ConnectToHotspot(void); + +void DisconnectWithHotspot(int netId); + +#endif // WIFI_CONNECTER_H \ No newline at end of file