def sim_hop(): ber = 0.0001 chunk_size = 50 per = 1 - (1 - ber)**(chunk_size * 8) loop_num = 5 hop = range(1, 6) w1_size = 0.4 p1 = 0.4 for h in tqdm(hop): fountain = EW_Fountain(m, chunk_size=chunk_size, w1_size=w1_size, w1_pro=p1) for j in tqdm(range(loop_num)): drop_id = 0 w1_done_t = 0 glass = Glass(Fountain.num_chunks) while not glass.isDone(): a_drop = fountain.droplet() ew_drop = EW_Droplet(a_drop.data, a_drop.seed, a_drop.num_chunks, w1_size, w1_pro=p1) glass.addDroplet(ew_drop) if glass.is_w1_done() and w1_done_t == 0: w1_done_t = drop_id del a_drop del ew_drop
def sim_chunk_size(): test_dir = os.path.join(SIM_PATH, 'sim_chunk_size') if not os.path.exists(test_dir): os.mkdir(test_dir) test_res_file = os.path.join( test_dir, time.asctime().replace(' ', '_').replace(':', '_')) + '.csv' # chunk_sizees = [int(ii) for ii in np.logspace(1.7, 4.99, 20)] chunk_sizees = range(100, 5050, 50) # chunk_sizees.reverse() code_rate = [0] * len(chunk_sizees) drops_num = [0] * len(chunk_sizees) per_list = [0] * len(chunk_sizees) i = 0 loop_num = 100 BER = 0.00001 for size in tqdm(chunk_sizees): for j in tqdm(range(loop_num)): fountain = EW_Fountain(m, chunk_size=size, seed=255) glass = Glass(fountain.num_chunks) drop_id = 0 PER = 1 - (1 - BER)**(size * 8) while not glass.isDone(): drop_id += 1 a_drop = fountain.droplet() ew_drop = EW_Droplet(a_drop.data, a_drop.seed, a_drop.num_chunks) glass.addDroplet(ew_drop) code_rate[i] += size * drop_id / (1 - PER) drops_num[i] += drop_id per_list[i] = PER i += 1 code_rate = [float(ii) / (len(m) * loop_num) for ii in code_rate] drops_num = [float(ii) / loop_num for ii in drops_num] df_res = pd.DataFrame({ "size": chunk_sizees, "code_rate": code_rate, 'drops_num': drops_num, 'loop_num': [loop_num for ii in chunk_sizees], 'BER': [BER for ii in chunk_sizees], 'PER': per_list }) df_res.to_csv(test_res_file) return test_res_file
def main_test_ew_fountain(): m = open(os.path.join(DOC_PATH, 'fountain.txt'), 'r').read() fountain = EW_Fountain(m, chunk_size=10) glass = Glass(fountain.num_chunks) ew_drop = None i = 0 drop_size = 0 while not glass.isDone(): i += 1 a_drop = fountain.droplet() ew_drop = EW_Droplet(a_drop.data, a_drop.seed, a_drop.num_chunks) drop_size = len(ew_drop.data) glass.addDroplet(ew_drop) # sleep(1) logging.info('+++++++++++++++++++++++++++++') logging.info(glass.getString()) logging.info("data size : {}".format(len(m))) logging.info("send drop num : {} drop size : {}".format(i, drop_size)) logging.info("send data size : {}".format(i * drop_size)) logging.info("scale : {}".format((i * drop_size) / float(len(m)))) logging.info('done')
class Receiver: def __init__( self, bus, device, ): self.spiRecv = spidev.SpiDev() self.spiRecv.open(bus, device) self.spiRecv.max_speed_hz = 6250000 #976000 self.spiRecv.mode = 0b00 self.spiSend = spidev.SpiDev() self.spiSend.open(bus, 0) self.spiSend.max_speed_hz = 6250000 #976000 self.spiSend.mode = 0b00 spi_init() self.drop_id = 0 self.glass = Glass(0) self.chunk_size = 0 self.recv_done_flag = False self.feedback_ack_flag = False self.chunk_process = [] self.feedback_idx = 0 self.data_rec = "" self.recv_dir = os.path.join( RECV_PATH, time.asctime().replace(' ', '_').replace(':', '_')) '''LT喷泉码接收解码部分''' def begin_to_catch(self): a_drop_bytes = self.catch_a_drop_spi() # bytes if a_drop_bytes is not None: self.drop_id += 1 print("====================") print("Recv dropid : ", self.drop_id) print("====================") if len(a_drop_bytes) > 0: check_data = recv_check(a_drop_bytes) if not check_data == None: self.drop_byte_size = len(check_data) self.add_a_drop(check_data) # bytes --- drop --- bits def catch_a_drop_spi(self): if GPIO.input(25): spi_recv = self.spiRecv.readbytes(239) rec_bytes = bytes(spi_recv) frame_len = len(rec_bytes) print("framelen: ", frame_len) if (frame_len > 1): while (rec_bytes[frame_len - 1] == 0 and frame_len >= 1): frame_len = frame_len - 1 rec_bytes = rec_bytes[:frame_len] print("droplen: ", frame_len) self.data_rec = rec_bytes if self.data_rec[0:2] == b'##' and self.data_rec[ frame_len - 2:frame_len] == b'$$': data_array = bytearray(self.data_rec) data_array.pop(0) data_array.pop(0) data_array.pop() data_array.pop() return bytes(data_array) else: print(self.data_rec) print('Wrong receive frame !') def add_a_drop(self, d_byte): drop = self.glass.droplet_from_Bytes(d_byte) # drop if self.glass.num_chunks == 0: print('init num_chunks : ', drop.num_chunks) self.glass = Glass(drop.num_chunks) # 初始化接收glass self.chunk_size = len(drop.data) #若为ew,则需要将drop转为ewdrop,两个drop里译码方式不一样 ew_drop = EW_Droplet(drop.data, drop.seed, drop.num_chunks, drop.process, drop.func_id, drop.feedback_idx) print('drop data len: ', len(drop.data)) self.glass.addDroplet(drop) # glass add drops logging.info('=============================') logging.info('Decode Progress: ' + str(self.glass.chunksDone()) + '/' + str(self.glass.num_chunks)) logging.info('=============================') # 接收完成 if self.glass.isDone(): self.recv_done_flag = True logging.info('============Recv done===========') # 接收完成写入图像 img_data = self.glass.get_bits() os.mkdir(self.recv_dir) with open(os.path.join(self.recv_dir, "img_recv" + ".jpg"), 'wb') as f: f.write(img_data) self.send_recv_done_ack() # 接收完成返回ack # 接收到K个数据包之后 if self.drop_id >= self.glass.num_chunks: if (self.drop_id - self.glass.num_chunks) % 10 == 0: self.chunk_process = self.glass.getProcess() # 用于返回进程包 self.glass.glass_process_history.append( self.chunk_process) # 添加反馈历史数据,用于droplet参数,正确译码 self.send_feedback() print("Feedback chunks: ", self.chunk_process) print("Feedback chunks num: ", len(self.chunk_process)) print("Feedback idx: ", self.feedback_idx) self.feedback_idx += 1 def send_recv_done_ack(self): if self.recv_done_flag: ack = b'#$' acklen = len(ack) acksend = bytearray(ack) while (acklen < 239): acksend.insert(acklen, 0) acklen += 1 self.spiSend.xfer2(acksend) logging.info('Send fountain ACK done') logging.info('Recv drops: ' + str(self.drop_id)) logging.info('Wrong frame drops: ' + str(self.drop_id)) logging.info('Wrong checksum drops: ' + str(self.drop_id)) def send_feedback(self): fb = b'$#' for chunk_id in self.chunk_process: chunk_id_bits = format(int(chunk_id), "016b") fb += bitarray.bitarray(chunk_id_bits).tobytes() fblen = len(fb) fbsend = bytearray(fb) while (fblen < 239): fbsend.insert(fblen, 0) fblen += 1 self.spiSend.xfer2(fbsend)
class Receiver: def __init__( self, bus, device, port, baudrate, timeout, ): self.spiRecv = spidev.SpiDev() self.spiRecv.open(bus, device) self.spiRecv.max_speed_hz = 6250000 #976000 self.spiRecv.mode = 0b00 self.spiSend = spidev.SpiDev() self.spiSend.open(bus, 0) self.spiSend.max_speed_hz = 6250000 #976000 self.spiSend.mode = 0b00 # 串口和spi初始化 spi_init() self.port = serial.Serial(port, baudrate) self.packet_id = 0 # 数据包数量 self.drop_id = 0 # 校验正确的有效数据包数量 self.real_drop_id = 0 # dropid除去度函数切换和进度包更新时收到的drop self.glass = Glass(0) self.chunk_size = 0 self.recv_done_flag = False self.feedback_ack_flag = False # 用于度函数切换过程不接收 self.feedback_send_done = False self.chunk_process = [] self.feedback_idx = 0 self.data_rec = "" self.recv_dir = os.path.join( RECV_PATH, time.asctime().replace(' ', '_').replace(':', '_')) # 吞吐量统计 self.packid_save = [] self.dropid_save = [] self.valid_dropid_save = [] self.packs_per_sec = [] self.drops_per_sec = [] self.valid_drops_per_sec = [] self.ttl_timer_start = False self.t0 = 0 self.t1 = 0 self.process_bytes = b'' self.decode_time = [] # 用于统计每个编码包的译码时间 '''LT喷泉码接收解码部分''' def begin_to_catch(self): a_drop_bytes = self.catch_a_drop_spi() # bytes if a_drop_bytes is not None: decode_t0 = time.time() # 从收到第一个包之后,开启定时记录吞吐量线程,记录时间 if self.ttl_timer_start == False: self.t0 = time.time() self.creat_ttl_Timer() self.ttl_timer_start = True self.packet_id += 1 print("Recv Packet id : ", self.packet_id) if len(a_drop_bytes) > 0: check_data = recv_check(a_drop_bytes) # 接收校验 if not check_data == None: self.drop_byte_size = len(check_data) self.add_a_drop(check_data) # bytes --- drop --- bits decode_t1 = time.time() self.decode_time.append(decode_t1 - decode_t0) def catch_a_drop_spi(self): if GPIO.input(25): spi_recv = self.spiRecv.readbytes(239) rec_bytes = bytes(spi_recv) frame_len = len(rec_bytes) print("framelen: ", frame_len) # 去掉末尾补充的0 if (frame_len > 1): while (rec_bytes[frame_len - 1] == 0 and frame_len >= 1): frame_len = frame_len - 1 rec_bytes = rec_bytes[:frame_len] print("droplen: ", frame_len) self.data_rec = rec_bytes # 判断帧头帧尾 if self.data_rec[0:2] == b'##' and self.data_rec[ frame_len - 2:frame_len] == b'$$': data_array = bytearray(self.data_rec) data_array.pop(0) data_array.pop(0) data_array.pop() data_array.pop() return bytes(data_array) else: print(self.data_rec) print('Wrong receive frame !') def add_a_drop(self, d_byte): self.drop_id += 1 print("====================") print("Recv dropid : ", self.drop_id) print("====================") print('glass_process_history len: ', len(self.glass.glass_process_history)) drop = self.glass.droplet_from_Bytes(d_byte) # drop if self.glass.num_chunks == 0: print('init num_chunks : ', drop.num_chunks) self.glass = Glass(drop.num_chunks) # 初始化接收glass self.chunk_size = len(drop.data) #若为ew,则需要将drop转为ewdrop,两个drop里译码方式不一样 ew_drop = EW_Droplet(drop.data, drop.seed, drop.num_chunks, drop.process, drop.func_id, drop.feedback_idx) print('drop data len: ', len(drop.data)) self.glass.addDroplet(ew_drop) # 这里解决度函数切换过程不接收,解决进度包更新过程不接收 # if (self.feedback_ack_flag==False) or (self.feedback_ack_flag==True and ew_drop.func_id==1 and ew_drop.feedback_idx==self.feedback_idx-1): # self.real_drop_id += 1 # self.glass.addDroplet(ew_drop) # glass add drops # print("=============================================================") # print("除去度函数切换和进度包更新时收到的drop,Real_Recv_dropid : ", self.real_drop_id) # print("=============================================================") # self.feedback_send_done=False logging.info('=============================') logging.info('Decode Progress: ' + str(self.glass.chunksDone()) + '/' + str(self.glass.num_chunks)) logging.info('=============================') # 接收完成 if self.glass.isDone(): self.recv_done_flag = True self.t1 = time.time() logging.info('============Recv done===========') logging.info("Fountain time elapsed:" + str(self.t1 - self.t0)) # 接收完成写入图像 img_data = self.glass.get_bits() os.mkdir(self.recv_dir) with open(os.path.join(self.recv_dir, "img_recv" + ".bmp"), 'wb') as f: f.write(img_data) # 串口模拟水声延迟进行反馈 t1 = threading.Timer(1.8, self.send_recv_done_ack) t1.start() # 实际写入水声通信机进行反馈 # self.send_recv_done_ack() # 接收完成返回ack # 记录吞吐量 self.cal_ttl() print('packet_id history: ', self.packid_save, len(self.packid_save)) print('packets_per_sec: ', self.packs_per_sec, len(self.packs_per_sec)) print('drop_id history: ', self.dropid_save, len(self.dropid_save)) logging.info('Send Sonic Fountain ACK done') logging.info('Recv Packets: : ' + str(self.packet_id)) logging.info('Recv drops: ' + str(self.drop_id)) logging.info('Feedback num: ' + str(self.feedback_idx)) print('drops_per_sec: ', self.drops_per_sec, len(self.drops_per_sec)) res = pd.DataFrame({ 'packet_id_history': self.packid_save, 'packets_per_sec': self.packs_per_sec, 'drop_id_history': self.dropid_save, 'drops_per_sec': self.drops_per_sec }) res.to_csv( ('data_save/Recv_ttl' + '_' + time.asctime().replace(' ', '_').replace(':', '_') + '.csv'), mode='a') # print('avgs_decode_time: ', float(sum(self.decode_time)/len(self.decode_time))) # print('max_decode_time:', max(self.decode_time)) # print('min_decode_time:', min(self.decode_time)) # 反馈 n1 = self.glass.w1_done_dropid n2 = 30 if self.glass.is_w1_done(0.6) and self.recv_done_flag == False: if (self.drop_id - n1) % n2 == 0: process = self.glass.getProcess() # 用于添加反馈历史数据, 用于droplet参数,正确译码 self.chunk_process = process[0] self.glass.glass_process_history.append(self.chunk_process) # 用于实际反馈 process_bitmap = process[1] # self.process_bytes = self.bit2hex(process_bitmap) # 实际水声通信机反馈可能需要用到这个 # print(process_bitmap) # print(self.process_bytes) process_bits = bitarray.bitarray(process_bitmap) self.process_bytes = process_bits.tobytes() # 串口模拟水声延迟进行反馈 t = threading.Timer(1.8, self.send_feedback) t.start() # 实际写入水声通信机进行反馈 # self.send_feedback() print("Feedback chunks: ", self.chunk_process) print("Feedback chunks num: ", len(self.chunk_process)) print("Feedback idx: ", self.feedback_idx) self.feedback_idx += 1 self.feedback_ack_flag = True self.feedback_send_done = True # 定时器线程每隔1s记录发包数,即吞吐量 def save_throughout_put(self): if (self.recv_done_flag == False): self.packid_save.append(self.packet_id) self.dropid_save.append(self.drop_id) self.valid_dropid_save.append(self.real_drop_id) self.creat_ttl_Timer() def creat_ttl_Timer(self): if (self.recv_done_flag == False): t = threading.Timer(1, self.save_throughout_put) t.start() # 计算吞吐量 def cal_ttl(self): idx = 0 while idx < len(self.packid_save): if idx == 0: self.packs_per_sec.append(self.packid_save[0]) else: self.packs_per_sec.append(self.packid_save[idx] - self.packid_save[idx - 1]) idx += 1 idx = 0 while idx < len(self.dropid_save): if idx == 0: self.drops_per_sec.append(self.dropid_save[0]) else: self.drops_per_sec.append(self.dropid_save[idx] - self.dropid_save[idx - 1]) idx += 1 # 串口发送译码完成ack def send_recv_done_ack(self): if self.recv_done_flag: # M = b'M\r\n' # self.port.write(M) # self.port.flushOutput() # time.sleep(0.01) ack = b'#$\r\n' acksend = bytearray(ack) self.port.write(acksend) self.port.flushOutput() # 串口反馈译码进度 def send_feedback(self): fb = b'$#' + self.process_bytes + b'\r\n' # M = b'M\r\n' # self.port.write(M) # self.port.flushOutput() # time.sleep(0.01) self.port.write(fb) self.port.flushOutput() def bit2hex(self, bit_array_source): bit_array = bit_array_source a = len(bit_array) % 4 for j in range(0, a): bit_array.append(0) result = b'' i = 0 while i < len(bit_array): bit4 = bit_array[i:i + 4] if (bit4 == [0, 0, 0, 0]): result += b'0' elif (bit4 == [0, 0, 0, 1]): result += b'1' elif (bit4 == [0, 0, 1, 0]): result += b'2' elif (bit4 == [0, 0, 1, 1]): result += b'3' elif (bit4 == [0, 1, 0, 0]): result += b'4' elif (bit4 == [0, 1, 0, 1]): result += b'5' elif (bit4 == [0, 1, 1, 0]): result += b'6' elif (bit4 == [0, 1, 1, 1]): result += b'7' elif (bit4 == [1, 0, 0, 0]): result += b'8' elif (bit4 == [1, 0, 0, 1]): result += b'9' elif (bit4 == [1, 0, 1, 0]): result += b'a' elif (bit4 == [1, 0, 1, 1]): result += b'b' elif (bit4 == [1, 1, 0, 0]): result += b'c' elif (bit4 == [1, 1, 0, 1]): result += b'd' elif (bit4 == [1, 1, 1, 0]): result += b'e' elif (bit4 == [1, 1, 1, 1]): result += b'f' i += 4 return result
class NodeRLY: def __init__(self, portSNC, baudrateSNC, timeoutSNC, portROV, baudrateROV, timeoutROV): self.ID = 1 #本节点id self.routing_table = [0, 1, 2] #路由 self.snc_handshake_done = False self.vlc_handshake_done = False self.vlc_handshake_timedout = False # 初始化spi发送 self.spiSend = spidev.SpiDev() self.spiSend.open(0, 0) # bus device self.spiSend.max_speed_hz = 6250000 #976000 self.spiSend.mode = 0b00 # 初始化spi接收 self.spiRecv = spidev.SpiDev() self.spiRecv.open(0, 1) self.spiRecv.max_speed_hz = 6250000 #976000 self.spiRecv.mode = 0b00 # 初始化光通信spi、水声串口、ROV串口 spi_init() self.acoustic = Acoustic(portSNC, baudrateSNC, timeoutSNC) self.rov = ROV(portROV, baudrateROV, timeoutROV) # 自动对准 self.align_rov_state = 0 #记录上次循环的转向状态,0为左,1为右 # 喷泉码接收 self.rx_packet_id = 0 self.rx_drop_id = 0 self.glass = Glass(0) self.chunk_size = 0 self.recv_done_flag = False self.feedback_ack_flag = False # 用于度函数切换过程不接收 self.chunk_process = [] self.feedback_idx = 0 self.data_rec = "" self.recv_dir = os.path.join( RECV_PATH, time.asctime().replace(' ', '_').replace(':', '_')) self.rx_packid_save = [] self.rx_dropid_save = [] self.rx_packs_per_sec = [] self.rx_drops_per_sec = [] self.rx_ttl_timer_start = False self.t0 = 0 self.t1 = 0 self.process_bytes = b'' self.img_recv_bits = bitarray.bitarray(endian='big') self.decode_time = [] # 喷泉码中继发送 self.tx_drop_id = 0 self.recvdone_ack = False self.chunk_process = [] self.feedback_num = 0 self.tx_dropid_save = [] '''LT喷泉码接收解码部分''' def begin_to_catch(self): a_drop_bytes = self.catch_a_drop_spi() # bytes if a_drop_bytes is not b'': decode_t0 = time.time() # 从收到第一个包之后,开启定时记录吞吐量线程,记录时间 if self.rx_ttl_timer_start == False: self.t0 = time.time() self.creat_ttl_Timer() self.rx_ttl_timer_start = True self.rx_packet_id += 1 print("Recv Packet id : ", self.rx_packet_id) if len(a_drop_bytes) > 0: check_data = recv_check(a_drop_bytes) if not check_data == b'': self.add_a_drop(check_data) # bytes --- drop --- bits def catch_a_drop_spi(self): if GPIO.input(25): spi_recv = self.spiRecv.readbytes(239) rec_bytes = bytes(spi_recv) frame_len = len(rec_bytes) print("framelen: ", frame_len) if (frame_len > 1): while (rec_bytes[frame_len - 1] == 0 and frame_len >= 1): frame_len = frame_len - 1 rec_bytes = rec_bytes[:frame_len] print("droplen: ", frame_len) self.data_rec = rec_bytes if self.data_rec[0:2] == b'##' and self.data_rec[ frame_len - 2:frame_len] == b'$$': data_array = bytearray(self.data_rec) data_array.pop(0) data_array.pop(0) data_array.pop() data_array.pop() return bytes(data_array) else: print(self.data_rec) print('Wrong receive frame !') return b'' else: return b'' def add_a_drop(self, d_byte): self.rx_drop_id += 1 print("====================") print("Recv dropid : ", self.rx_drop_id) print("====================") print('glass_process_history len: ', len(self.glass.glass_process_history)) drop = self.glass.droplet_from_Bytes(d_byte) # drop if self.glass.num_chunks == 0: print('init num_chunks : ', drop.num_chunks) self.glass = Glass(drop.num_chunks) # 初始化接收glass self.chunk_size = len(drop.data) #若为ew,则需要将drop转为ewdrop,两个drop里译码方式不一样 ew_drop = EW_Droplet(drop.data, drop.seed, drop.num_chunks, drop.process, drop.func_id, drop.feedback_idx) print('drop data len: ', len(drop.data)) self.glass.addDroplet(ew_drop) logging.info('=============================') logging.info('Decode Progress: ' + str(self.glass.chunksDone()) + '/' + str(self.glass.num_chunks)) logging.info('=============================') # 接收完成 if self.glass.isDone(): self.recv_done_flag = True self.t1 = time.time() logging.info('============Recv done===========') logging.info("Fountain time elapsed:" + str(self.t1 - self.t0)) # 接收完成写入图像 img_data = self.glass.get_bits() self.img_recv_bits = img_data os.mkdir(self.recv_dir) with open(os.path.join(self.recv_dir, "img_recv" + ".bmp"), 'wb') as f: f.write(img_data) self.send_recv_done_ack() # 接收完成返回ack # 记录吞吐量 self.rx_cal_ttl() logging.info('Recv drops: ' + str(self.rx_drop_id)) logging.info('Feedback num: ' + str(self.feedback_idx)) print('drops_per_sec: ', self.rx_drops_per_sec, len(self.rx_drops_per_sec)) res = pd.DataFrame({ 'packet_id_history': self.rx_packid_save, 'packets_per_sec': self.rx_packs_per_sec, 'drop_id_history': self.rx_dropid_save, 'drops_per_sec': self.rx_drops_per_sec }) res.to_csv( ('data_save/Recv_ttl' + '_' + time.asctime().replace(' ', '_').replace(':', '_') + '.csv'), mode='a') # 反馈 n1 = self.glass.w1_done_dropid n2 = 30 if self.glass.is_w1_done(0.6) and self.recv_done_flag == False: if (self.rx_drop_id - n1) % n2 == 0: process = self.glass.getProcess() # 用于添加反馈历史数据, 用于droplet参数,正确译码 self.chunk_process = process[0] self.glass.glass_process_history.append(self.chunk_process) # 用于实际反馈 process_bitmap = process[1] # self.process_bytes = self.bit2hex(process_bitmap) # print(process_bitmap) # print(self.process_bytes) process_bits = bitarray.bitarray(process_bitmap) self.process_bytes = process_bits.tobytes() self.send_feedback() print("Feedback chunks: ", self.chunk_process) print("Feedback chunks num: ", len(self.chunk_process)) print("Feedback idx: ", self.feedback_idx) self.feedback_idx += 1 self.feedback_ack_flag = True # 定时器线程每隔1s记录收包数,即接收吞吐量 def rx_save_throughput(self): if (self.recv_done_flag == False): self.rx_packid_save.append(self.rx_packet_id) self.rx_dropid_save.append(self.rx_drop_id) self.rx_creat_ttl_Timer() def rx_creat_ttl_Timer(self): if (self.recv_done_flag == False): t = threading.Timer(1, self.rx_save_throughput) t.start() # 计算接收瞬时吞吐量 def rx_cal_ttl(self): idx = 0 while idx < len(self.rx_packid_save): if idx == 0: self.rx_packs_per_sec.append(self.rx_packid_save[0]) else: self.rx_packs_per_sec.append(self.rx_packid_save[idx] - self.rx_packid_save[idx - 1]) idx += 1 idx = 0 while idx < len(self.rx_dropid_save): if idx == 0: self.rx_drops_per_sec.append(self.rx_dropid_save[0]) else: self.rx_drops_per_sec.append(self.rx_dropid_save[idx] - self.rx_dropid_save[idx - 1]) idx += 1 def send_recv_done_ack(self): if self.recv_done_flag: self.acoustic.mfsk_tx_config() self.acoustic.mfsk_tx(b'#$\r\n') self.port.flushOutput() def send_feedback(self): self.acoustic.mfsk_tx_config() fb = b'$#' + self.process_bytes + b'\r\n' self.acoustic.mfsk_tx(fb) self.port.flushOutput() '''基于水声辅助的光通信链路建立部分''' # 等待水声握手,并反馈水声握手ACK def wait_acoustic_handshake(self): print("===...waiting for connection...===") self.acoustic.mfsk_rx_config() while True: str_recv = self.acoustic.mfsk_rx() # 收到水声握手包 if str_recv[0:2] == "##": var = self.acoustic.acoustic_handshake_pack_res(str_recv[2:]) # 反馈水声握手ACK if var[0] == self.ID: self.acoustic.mfsk_tx_config() self.acoustic.mfsk_tx(b'##snc') self.snc_handshake_done = True break # 下面3个是ROV可见光通信自动对准程序 def rov_vlc_align(self): last_state = 1 #右转 start = time.time() align_flag = False #对准标志位 print("===Start to align===") while not align_flag: align_flag = self.align_stability_test() if not align_flag: if self.align_rov_state == 0: if (last_state == 1): print("===Rov turn right===") self.rov.port.write(b'#8868$') #右转 else: if (last_state == 0): print("===Rov turn left===") self.rov.port.write(b'#88a8$') #左转 last_state = self.align_rov_state #对准成功 if align_flag: print('===Align Successed!===') print("===Sending VLC handshake ACK===") self.vlc_handshake_done = True self.acoustic.mfsk_tx_config() self.acoustic.mfsk_tx(b'$$vlc') break #超过30s,对准失败 elif (time.time() - start) > 30: print('===Align Failed!===') self.vlc_handshake_done = False break # 稳定性测试 def align_stability_test(self): if self.align_vlc_rx(): #当前时刻能接收光信号 if self.align_rov_state == 0: #记录旋转状态,如因惯性过转,下次反转 self.align_rov_state = 1 else: self.align_rov_state = 0 print("===Rov stop===") self.rov.port.write(b'#0000$') #rov停转 time.sleep(1) #静止后仍然能接收光信号 print("===stop and receive===") rnum = 0 start = time.time() while True: if (self.align_vlc_rx()): rnum += 1 print("rnum = ", rnum) if (time.time() - start) > 3: if (rnum > 24): return True else: return False else: return False # 接收可见光通信探测包并检测 def align_vlc_rx(self): a_drop_bytes = self.catch_a_drop_spi() if a_drop_bytes is not b'': check_data = recv_check(a_drop_bytes) if check_data is not b'': print("Receive a valid packet!!!") return True else: return False else: return False '''中继转发部分''' def relay_forward(self): # 状态重新初始化 self.align_rov_state = 0 self.vlc_handshake_done = False self.snc_handshake_done = False self.vlc_handshake_timedout = False # 中继转发 print( '========================================================================' ) print( 'INFO: srcID=0, selfID=1, desID=2, starting Relay Forwarding procedure...' ) self.send_acoustic_handshake() self.wait_acoustic_handshake_ACK() if self.snc_handshake_done == True: self.rov_vlc_align() if self.vlc_handshake_done: time.sleep(3) print("===Starting data relay forwarding transfer===") self.fountain = EW_Fountain(self.img_recv_bits, chunk_size=215) self.send_drops_spi() else: print( "Acoustic handshake failed, Relay Forwarding Transmission Terminated !!!" ) # 寻找下一跳节点id def find_next_id(self): idx = 0 next_id = 0 for id in self.routing_table: if id == self.ID: next_id = self.routing_table[idx + 1] return next_id idx += 1 return None # 发送水声握手包 def send_acoustic_handshake(self): id = self.find_next_id() if id is not None: nextid = format(int(id), "08b") srcid = format(int(0), "08b") desid = format(int(2), "08b") w1size = format(int(6), "08b") imgW = format(int(256), "016b") imgH = format(int(256), "016b") SPIHTlen = format(int(len(self.m)), "032b") level = format(int(3), "08b") wavelet = format(int(1), "08b") # 1代表bior4.4 mode = format(int(1), "08b") # 1代表periodization acoustic_handshake = b'##' + bitarray.bitarray( nextid + srcid + desid + w1size + imgW + imgH + SPIHTlen + level + wavelet + mode).tobytes() # 切换成发送模式,发送水声握手包 print('===Send desID=2 acoustic broadcast handshake===') self.acoustic.mfsk_tx_config() self.acoustic.mfsk_tx(acoustic_handshake) else: print("nextID Not Found !!!") # 等待水声握手包的ACK def wait_acoustic_handshake_ACK(self): self.acoustic.mfsk_rx_config() snc_shake_time0 = time.time() snc_shake_retry_times = 0 while True: if self.acoustic.mfsk_rx() == "##snc": print( '===Acoustic handshake ACK received, Acoustic handshake done!===' ) self.snc_handshake_done = True break if (time.time() - snc_shake_time0) % 6 == 0: self.send_acoustic_handshake() snc_shake_retry_times += 1 if snc_shake_retry_times >= 3: break # 中继转发喷泉码 def a_drop(self): return self.fountain.droplet().toBytes() def send_drops_spi(self): # 启动反馈检测、吞吐量计算线程 self.tx_creat_ttl_Timer() self.creat_detect_feedback_Timer() # 主线程 while True: self.tx_drop_id += 1 # 发送一帧补0到239字节 sendbytes = send_check(self.a_drop()) sendbytearray = bytearray(sendbytes) datalen = len(sendbytearray) while (datalen < 239): sendbytearray.insert(datalen, 0) datalen += 1 self.spiSend.xfer2(sendbytearray) print("====================") print("Relay Forward Send dropid: ", self.tx_drop_id) print("====================") print("FountainFrameLen: ", len(self.a_drop())) print("SendFrameLen: ", len(sendbytearray)) if (self.recvdone_ack): logging.info('============Fountain Send done===========') logging.info('Send drops used: ' + str(self.tx_drop_id)) logging.info('Feedback num: ' + str(self.feedback_num)) # 记录吞吐量 throughput_list = cal_ttl(self.tx_dropid_save) # print('dropid history: ', self.dropid_save, len(self.dropid_save)) print('drops_per_sec: ', throughput_list, len(throughput_list)) res = pd.DataFrame({ 'dropid_history': self.tx_dropid_save, 'drops_per_sec': throughput_list }) res.to_csv( ('data_save/Send_ttl' + '_' + time.asctime().replace(' ', '_').replace(':', '_') + '.csv'), mode='a') break time.sleep(0.09) #发包间隔 # 定时器线程每隔1s记录发包数,即吞吐量 def tx_save_throughput(self): if (self.recvdone_ack == False): self.tx_dropid_save.append(self.tx_drop_id) self.tx_creat_ttl_Timer() def tx_creat_ttl_Timer(self): if (self.recvdone_ack == False): t = threading.Timer(1, self.tx_save_throughput) t.start() # 检测反馈 def feedback_detect(self): data_rec = self.acoustic.modem_feedback() if data_rec is not b'': data_str = str(data_rec, encoding="utf8") idx = data_str.find('Received String: ') if idx >= 0: msg_str = data_str[idx + 17:] msg_bytes = bytes(msg_str, encoding="utf-8") # msg_bytes = data_rec # 接收完成 if msg_bytes[:2] == b'#$': self.recvdone_ack = True # 进度包 elif msg_bytes[:2] == b'$#': self.fountain.all_at_once = True process_recv = self.get_process_from_feedback(msg_bytes) if process_recv == []: self.recvdone_ack = True else: self.chunk_process = process_recv self.fountain.chunk_process = self.chunk_process self.fountain.feedback_idx = self.feedback_num self.feedback_num += 1 self.creat_detect_feedback_Timer() def creat_detect_feedback_Timer(self): if self.recvdone_ack == False: t = threading.Timer(0.001, self.feedback_detect) t.start() # 从反馈中获取进度 def get_process_from_feedback(self, rec_bytes): process = [] chunk_id = 0 process_bits = bitarray.bitarray(endian='big') process_bits.frombytes(rec_bytes[2:]) while chunk_id < self.fountain.num_chunks: if (process_bits[chunk_id] == False): process.append(chunk_id) chunk_id += 1 return process
class Receiver: def __init__( self, port, baudrate, timeout, ): self.port = serial.Serial(port, baudrate) # if (self.port.is_open): # print("串口{}打开成功".format(self.port.portstr)) # else: # print("串口打开失败") self.eng = matlab.engine.start_matlab() self.eng.addpath(LIB_PATH) self.drop_id = 0 self.glass = Glass(0) self.chunk_size = 0 self.current_recv_bits_len = 0 self.i_spiht = [] self.i_dwt = [[], [], []] self.img_mat = [] # 暂时 self.idwt_coeff_r = None self.r_mat = None self.img_shape = [0, 0] self.recv_img = None self.drop_byte_size = 99999 self.test_dir = os.path.join( TEST_PATH, time.asctime().replace(' ', '_').replace(':', '_')) self.w1_done = True self.recv_done_flag = False self.wlt_ds = 0 self.detect_done = False '探测序列检测部分,检测完成返回ack' def detect_exam(self): success_times = 0 recv_id = 0 while recv_id < 10: recv_bytes = self.catch_a_drop_use_serial() if recv_bytes is not None: recv_id += 1 print('recv id:', recv_id) results = recv_check(recv_bytes) if not results == None: success_times += 1 print('success rate:{}/{}'.format(success_times, recv_id)) success_rate = float(success_times / 10) if success_rate > 0.5: self.detect_done = True self.send_detect_ack() def send_detect_ack(self): ack_good = b'ok' ack_bad = b'no' if self.detect_done: self.port.write(ack_good) self.port.flushOutput() else: self.port.write(ack_bad) self.port.flushOutput() print('send detect ack done') '''LT喷泉码接收解码部分''' def begin_to_catch(self): a_drop_bytes = self.catch_a_drop_use_serial() # bytes if a_drop_bytes is not None: check_data = recv_check(a_drop_bytes) # if check_data is None: # self.begin_to_catch() # else: if not check_data == None: self.drop_id += 1 print("recv drops id : ", self.drop_id) self.drop_byte_size = len(check_data) self.add_a_drop(check_data) # bytes --- drop --- bits data_rec = '' def catch_a_drop_use_serial(self): time.sleep(1) size1 = self.port.in_waiting if size1: self.data_rec = self.port.read_all() frame_len = len(self.data_rec) if self.data_rec[0:2] == b'ok' and self.data_rec[ frame_len - 4:frame_len] == b'fine': data_array = bytearray(self.data_rec) data_array.pop(0) data_array.pop(0) data_array.pop() data_array.pop() data_array.pop() data_array.pop() a = len(bytes(data_array)) print('drop len(crc) :', a) return bytes(data_array) else: print('Wrong receive frame !') else: self.port.flushInput() def add_a_drop(self, d_byte): recv_time_start = time.time() drop = self.glass.droplet_from_Bytes(d_byte) # drop print('drop data len: ', len(drop.data)) if self.glass.num_chunks == 0: print('init num_chunks : ', drop.num_chunks) self.glass = Glass(drop.num_chunks) # 初始化接收glass self.chunk_size = len(drop.data) lt_decode_start = time.time() self.glass.addDroplet(drop) # glass add drops logging.info('current chunks') logging.info( [ii if ii == None else '++++' for ii in self.glass.chunks]) if self.glass.isDone(): lt_decode_end = time.time() print('LT decode time:', lt_decode_end - lt_decode_start) self.recv_bit = self.glass.get_bits() # bits # a = self.recv_bit.length() print('recv bits length : ', int(self.recv_bit.length())) if (int(self.recv_bit.length()) > 0) and \ (self.recv_bit.length() > self.current_recv_bits_len): self.current_recv_bits_len = int(self.recv_bit.length()) self.i_spiht = self._123(self.recv_bit) try: SPIHT_time_start = time.time() self.i_dwt[0] = spiht_decode(self.i_spiht[0], self.eng) self.i_dwt[1] = spiht_decode(self.i_spiht[1], self.eng) self.i_dwt[2] = spiht_decode(self.i_spiht[2], self.eng) self.img_mat = [func_IDWT(ii) for ii in self.i_dwt] SPIHT_time_end = time.time() print('SPIHT decode time:', SPIHT_time_end - SPIHT_time_start) print('recv time total cost:', SPIHT_time_end - recv_time_start) # 单通道处理 # self.idwt_coeff_r = spiht_decode(self.recv_bit, self.eng) # self.r_mat =func_IDWT(self.idwt_coeff_r) self.img_shape = self.img_mat[0].shape self.show_recv_img() self.recv_done_flag = True self.send_recv_done_ack() except: print('Decode error in matlab') def show_recv_img(self): if self.recv_img == None: self.recv_img = Image.new('RGB', (self.img_shape[0], self.img_shape[0]), (0, 0, 20)) for i in range(self.img_shape[0]): for j in range(self.img_shape[0]): R = self.img_mat[0][i, j] G = self.img_mat[1][i, j] B = self.img_mat[2][i, j] # 单通道处理 # G = self.r_mat[i, j] # G = 255 # B = 255 new_value = (int(R), int(G), int(B)) self.recv_img.putpixel((i, j), new_value) self.recv_img.show() self.recv_img.save( os.path.join(self.test_dir, str(self.drop_id)) + ".bmp") def _123(self, bits): # 将rgb拆成r,g,b self.recv_bit_len = int(bits.length()) i_spiht_list = [] # if bits % 3 == 0: # print('') # chunk_size = self.chunk_size rgb_chunk_bit_size = 12000 print('self.glass.chunk_bit_size : ', self.glass.chunk_bit_size) # bits.tofile(open(str(self.drop_id), 'w')) each_chunk_size = int(rgb_chunk_bit_size / 3) r_bits = bitarray.bitarray('') g_bits = bitarray.bitarray('') b_bits = bitarray.bitarray('') print('recv_bit len : ', bits.length()) for i in range( int(ceil(int(bits.length()) / float(rgb_chunk_bit_size)))): start = i * rgb_chunk_bit_size end = min((i + 1) * rgb_chunk_bit_size, int(bits.length())) tap_chunk = bits[start:end] r_bits += tap_chunk[each_chunk_size * 0:each_chunk_size * 1] g_bits += tap_chunk[each_chunk_size * 1:each_chunk_size * 2] b_bits += tap_chunk[each_chunk_size * 2:] rgb = list('rgb') # r_bits.tofile(open("r_"+str(self.drop_id), 'w')) rgb_bits = [r_bits, g_bits, b_bits] return rgb_bits def w1_123(self, w1_bits): # 将rgb拆成r,g,b self.recv_bit_len = int(w1_bits.length()) i_spiht_list = [] # if bits % 3 == 0: # print('') # chunk_size = self.chunk_size rgb_chunk_bit_size = 12000 print('self.glass.chunk_bit_size : ', self.glass.chunk_bit_size) each_chunk_bit_size = int(rgb_chunk_bit_size / 3) r_bits = bitarray.bitarray('') g_bits = bitarray.bitarray('') b_bits = bitarray.bitarray('') print('w1_bit len : ', w1_bits.length()) num_rgb_chunks = int( ceil(int(w1_bits.length()) / float(rgb_chunk_bit_size))) rgb_bits_left = int(w1_bits.length() % rgb_chunk_bit_size) for i in range(num_rgb_chunks): start = i * rgb_chunk_bit_size end = min((i + 1) * rgb_chunk_bit_size, int(w1_bits.length())) tap_chunk = w1_bits[start:end] if i == num_rgb_chunks - 1 and rgb_bits_left < each_chunk_bit_size: r_bits += tap_chunk[each_chunk_bit_size * 0:] break elif i == num_rgb_chunks - 1 and each_chunk_bit_size < rgb_bits_left < each_chunk_bit_size * 2: r_bits += tap_chunk[each_chunk_bit_size * 0:each_chunk_bit_size * 1] g_bits += tap_chunk[each_chunk_bit_size * 1:] break elif i == num_rgb_chunks - 1 and each_chunk_bit_size * 2 < rgb_bits_left < each_chunk_bit_size * 3: r_bits += tap_chunk[each_chunk_bit_size * 0:each_chunk_bit_size * 1] g_bits += tap_chunk[each_chunk_bit_size * 1:each_chunk_bit_size * 2] b_bits += tap_chunk[each_chunk_bit_size * 2:] r_bits += tap_chunk[each_chunk_bit_size * 0:each_chunk_bit_size * 1] g_bits += tap_chunk[each_chunk_bit_size * 1:each_chunk_bit_size * 2] b_bits += tap_chunk[each_chunk_bit_size * 2:] rgb = list('rgb') # r_bits.tofile(open("r_"+str(self.drop_id), 'w')) rgb_bits = [r_bits, g_bits, b_bits] return rgb_bits # self.recv_bit_len = int(bits.length()) # i_spiht_list = [] # # if bits % 3 == 0: # # print('') # # chunk_size = self.chunk_size # bit_chunk_size = self.glass.chunk_bit_size # # print('self.glass.chunk_bit_size : ', self.glass.chunk_bit_size) # # bits.tofile(open(str(self.drop_id), 'w')) # each_chunk_size = int(ceil(bit_chunk_size / 3)) ### # # each_chunk_size = 2500 ################### # r_bits = bitarray.bitarray('') # g_bits = bitarray.bitarray('') # b_bits = bitarray.bitarray('') # print('recv_bit len : ', bits.length()) # # for i in range(int(ceil(int(bits.length()) / float(bit_chunk_size)))): # start = i * bit_chunk_size # end = min((i + 1) * bit_chunk_size, int(bits.length())) ###*8 # tap_chunk = bits[start: end] # r_bits += tap_chunk[each_chunk_size * 0: each_chunk_size * 1] # g_bits += tap_chunk[each_chunk_size * 1: each_chunk_size * 2] # b_bits += tap_chunk[each_chunk_size * 2:] # rgb = list('rgb') # # r_bits.tofile(open("r_"+str(self.drop_id), 'w')) # rgb_bits = [r_bits, g_bits, b_bits] # return rgb_bits def send_recv_done_ack(self): if self.recv_done_flag: ack = b'recv' self.port.write(ack) self.port.flushOutput() print('send recv_done_ack done') '''RS接收解码部分''' def catch_rs_use_serial(self): time.sleep(1) size1 = self.port.in_waiting if size1 == 0: # print('\r', 'serial port listening......', end='') print('serial port listening......') self.catch_rs_use_serial() elif size1: self.data_rec = self.port.read_all() data_array = bytearray(self.data_rec) self.port.flushInput() return bytes(data_array) def rs_recv_main(self): recv_time_start = time.time() self.recv_byte = self.catch_rs_use_serial() if self.recv_byte is not None: rs_decode_start = time.time() rs_decoded = rs_decode_image(self.recv_byte) rs_decode_end = time.time() print('RS decode time:', rs_decode_end - rs_decode_start) bitarray_factory = bitarray.bitarray(endian='big') bitarray_factory.frombytes(rs_decoded) # if bitarray_factory is not None: # test = int(ceil(len(bitarray_factory) / 5)) self.i_spiht = self._123(bitarray_factory) try: SPIHT_time_start = time.time() self.i_dwt[0] = spiht_decode(self.i_spiht[0], self.eng) self.i_dwt[1] = spiht_decode(self.i_spiht[1], self.eng) self.i_dwt[2] = spiht_decode(self.i_spiht[2], self.eng) self.img_mat = [func_IDWT(ii) for ii in self.i_dwt] SPIHT_time_end = time.time() print('SPIHT decode time:', SPIHT_time_end - SPIHT_time_start) self.img_shape = self.img_mat[0].shape self.show_recv_img() self.recv_done_flag = True recv_time_end = time.time() print('recv time total cost:', recv_time_end - recv_time_start) self.send_recv_done_ack() except: print('Decode error in matlab')
class EW_Receiver(Receiver): def __init__(self, port, baudrate, timeout, recv_img=None): Receiver.__init__(self, port=port, baudrate=baudrate, timeout=timeout) def add_a_drop(self, d_byte): a_drop = self.glass.droplet_from_Bytes(d_byte) print("seed: {}\tnum_chunk : {}\tdata len: {}".format( a_drop.seed, a_drop.num_chunks, len(a_drop.data))) ew_drop = EW_Droplet(a_drop.data, a_drop.seed, a_drop.num_chunks) if self.glass.num_chunks == 0: self.wlt_ds = time.time() print('init num_chunks : ', a_drop.num_chunks) self.glass = Glass(a_drop.num_chunks) self.chunk_size = len(a_drop.data) self.glass.addDroplet(ew_drop) logging.info('current chunks') logging.info( [ii if ii == None else '++++' for ii in self.glass.chunks]) # 解码w1信息 w1_size = 0.1 if self.glass.is_w1_done(w1_size) and self.w1_done: print('w1_data complete!') w1_bits = self.glass.get_w1_bits( int(round(self.glass.num_chunks * w1_size))) self.w1_done = False if (int(w1_bits.length()) > 0) and \ (w1_bits.length() > self.current_recv_bits_len): self.current_recv_bits_len = w1_bits.length() self.i_spiht = self.w1_123(w1_bits) try: self.i_dwt[0] = spiht_decode(self.i_spiht[0], self.eng) self.i_dwt[1] = spiht_decode(self.i_spiht[1], self.eng) self.i_dwt[2] = spiht_decode(self.i_spiht[2], self.eng) self.img_mat = [func_IDWT(ii) for ii in self.i_dwt] # 单通道处理 # self.idwt_coeff_r = spiht_decode(self.recv_bit, self.eng) # self.r_mat =func_IDWT(self.idwt_coeff_r) self.img_shape = self.img_mat[0].shape self.show_recv_img() except: print('decode error in matlab') # 解码全部信息 if self.glass.isDone(): # 喷泉码接收译码完成 wlt_de = time.time() print('Window LT decode time used:', wlt_de - self.wlt_ds) self.recv_bit = self.glass.get_bits() # print('recv bits length : ', int(self.recv_bit.length())) if (int(self.recv_bit.length()) > 0) and \ (self.recv_bit.length() > self.current_recv_bits_len): self.current_recv_bits_len = self.recv_bit.length() self.i_spiht = self._123(self.recv_bit) try: spihtstart = time.time() self.i_dwt[0] = spiht_decode(self.i_spiht[0], self.eng) self.i_dwt[1] = spiht_decode(self.i_spiht[1], self.eng) self.i_dwt[2] = spiht_decode(self.i_spiht[2], self.eng) self.img_mat = [func_IDWT(ii) for ii in self.i_dwt] spihtend = time.time() print('SPIHT decode time:', spihtend - spihtstart) # 单通道处理 # self.idwt_coeff_r = spiht_decode(self.recv_bit, self.eng) # self.r_mat =func_IDWT(self.idwt_coeff_r) self.img_shape = self.img_mat[0].shape self.show_recv_img() self.recv_done_flag = True self.send_recv_done_ack() except: print('decode error in matlab')
class Receiver(): def __init__(self): self.drop_id = 0 self.eng = matlab.engine.start_matlab() self.eng.addpath(LIB_PATH) self.glass = Glass(0) self.chunk_size = 0 self.current_recv_bits_len = 0 self.i_spiht = [] self.i_dwt = [[], [], []] self.img_mat = [] # 暂时 self.idwt_coeff_r = None self.r_mat = None self.img_shape = [0, 0] self.recv_img = None self.drop_byte_size = 99999 self.test_dir = os.path.join( SIM_PATH, time.asctime().replace(' ', '_').replace(':', '_')) os.mkdir(self.test_dir) self.socket_recv = self.socket_builder() while True: self.begin_to_catch() if self.glass.isDone(): self.socket_recv.close() print('recv done') break def socket_builder(self): socket_recv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) socket_recv.connect((HOST, PORT)) return socket_recv def add_a_drop(self, d_byte): a_drop = self.glass.droplet_from_Bytes(d_byte) if self.glass.num_chunks == 0: print('init num_chunks : ', a_drop.num_chunks) self.glass = Glass(a_drop.num_chunks) self.chunk_size = len(a_drop.data) self.glass.addDroplet(a_drop) self.recv_bit = self.glass.get_bits() # print('recv bits length : ', int(self.recv_bit.length())) if (int(self.recv_bit.length()) > 0) and \ (self.recv_bit.length() > self.current_recv_bits_len): self.current_recv_bits_len = int(self.recv_bit.length()) # self.recv_bit.tofile(open('./recv_tmp.txt', 'w')) self.i_spiht = self._123(self.recv_bit, self.chunk_size) # self.i_dwt = [spiht_decode(ii, self.eng) for ii in self.i_spiht] try: self.i_dwt[0] = spiht_decode(self.i_spiht[0], self.eng) self.i_dwt[1] = spiht_decode(self.i_spiht[1], self.eng) self.i_dwt[2] = spiht_decode(self.i_spiht[2], self.eng) self.img_mat = [func_IDWT(ii) for ii in self.i_dwt] # 单通道处理 # self.idwt_coeff_r = spiht_decode(self.recv_bit, self.eng) # self.r_mat =func_IDWT(self.idwt_coeff_r) self.img_shape = self.img_mat[0].shape self.show_recv_img() except: print('decode error in matlab') def catch_a_drop_use_socket(self): return self.socket_recv.recv(self.drop_byte_size) def show_recv_img(self): if self.recv_img == None: self.recv_img = Image.new('RGB', (self.img_shape[0], self.img_shape[0]), (0, 0, 20)) for i in range(self.img_shape[0]): for j in range(self.img_shape[0]): R = self.img_mat[0][i, j] G = self.img_mat[1][i, j] B = self.img_mat[2][i, j] # 单通道处理 # G = self.r_mat[i, j] # G = 255 # B = 255 new_value = (int(R), int(G), int(B)) self.recv_img.putpixel((i, j), new_value) self.recv_img.show() self.recv_img.save( os.path.join(self.test_dir, str(self.drop_id)) + ".bmp") def begin_to_catch(self): a_drop = self.catch_a_drop_use_socket() if not a_drop == None: self.drop_id += 1 print("drops id : ", self.drop_id) self.drop_byte_size = len(a_drop) self.add_a_drop(a_drop) def _123(self, bits, chunk_size): self.recv_bit_len = int(bits.length()) i_spiht_list = [] # if bits % 3 == 0: # print('') # chunk_size = self.chunk_size chunk_size = self.glass.chunk_bit_size print('self.glass.chunk_bit_size : ', self.glass.chunk_bit_size) # bits.tofile(open(str(self.drop_id), 'w')) each_chunk_size = chunk_size / 3 r_bits = bitarray.bitarray('') g_bits = bitarray.bitarray('') b_bits = bitarray.bitarray('') print('recv_bit len : ', bits.length()) for i in range(int(ceil(int(bits.length()) / float(chunk_size)))): start = i * chunk_size end = min((i + 1) * chunk_size, int(bits.length())) * 8 tap_chunk = bits[start:end] r_bits += tap_chunk[each_chunk_size * 0:each_chunk_size * 1] g_bits += tap_chunk[each_chunk_size * 1:each_chunk_size * 2] b_bits += tap_chunk[each_chunk_size * 2:each_chunk_size * 3] rgb = list('rgb') # r_bits.tofile(open("r_"+str(self.drop_id), 'w')) rgb_bits = [r_bits, g_bits, b_bits] return rgb_bits
class Receiver: def __init__(self, bus, device): self.spiRecv = spidev.SpiDev() self.spiRecv.open(bus, device) self.spiRecv.max_speed_hz = 6250000 #976000 self.spiRecv.mode = 0b00 self.spiSend = spidev.SpiDev() self.spiSend.open(bus, 0) self.spiSend.max_speed_hz = 6250000 #976000 self.spiSend.mode = 0b00 # spi初始化 spi_init() self.packet_id = 0 self.drop_id = 0 self.real_drop_id = 0 # dropid除去度函数切换和进度包更新时收到的drop self.glass = Glass(0) self.chunk_size = 0 self.recv_done_flag = False self.feedback_ack_flag = False # 用于度函数切换过程不接收 self.feedback_send_done = False self.chunk_process = [] self.feedback_idx = 0 self.data_rec = "" self.recv_dir = os.path.join( RECV_PATH, time.asctime().replace(' ', '_').replace(':', '_')) self.packid_save = [] self.dropid_save = [] self.valid_dropid_save = [] self.packs_per_sec = [] self.drops_per_sec = [] self.valid_drops_per_sec = [] self.ttl_timer_start = False self.t0 = 0 self.t1 = 0 self.process_bytes = b'' '''LT喷泉码接收解码部分''' def begin_to_catch(self): a_drop_bytes = self.catch_a_drop_spi() # bytes if a_drop_bytes is not None: # 从收到第一个包之后,开启定时记录吞吐量线程,记录时间 if self.ttl_timer_start == False: self.t0 = time.time() self.creat_ttl_Timer() self.ttl_timer_start = True self.packet_id += 1 print("Recv Packet id : ", self.packet_id) if len(a_drop_bytes) > 0: check_data = recv_check(a_drop_bytes) if not check_data == None: self.drop_byte_size = len(check_data) self.add_a_drop(check_data) # bytes --- drop --- bits def catch_a_drop_spi(self): if GPIO.input(25): spi_recv = self.spiRecv.readbytes(239) rec_bytes = bytes(spi_recv) frame_len = len(rec_bytes) print("framelen: ", frame_len) if (frame_len > 1): while (rec_bytes[frame_len - 1] == 0 and frame_len >= 1): frame_len = frame_len - 1 rec_bytes = rec_bytes[:frame_len] print("droplen: ", frame_len) self.data_rec = rec_bytes if self.data_rec[0:2] == b'##' and self.data_rec[ frame_len - 2:frame_len] == b'$$': data_array = bytearray(self.data_rec) data_array.pop(0) data_array.pop(0) data_array.pop() data_array.pop() return bytes(data_array) else: print(self.data_rec) print('Wrong receive frame !') def add_a_drop(self, d_byte): self.drop_id += 1 print("====================") print("Recv dropid : ", self.drop_id) print("====================") drop = self.glass.droplet_from_Bytes(d_byte) # drop if self.glass.num_chunks == 0: print('init num_chunks : ', drop.num_chunks) self.glass = Glass(drop.num_chunks) # 初始化接收glass self.chunk_size = len(drop.data) #若为ew,则需要将drop转为ewdrop,两个drop里译码方式不一样 ew_drop = EW_Droplet(drop.data, drop.seed, drop.num_chunks, drop.process, drop.func_id, drop.feedback_idx) print('drop data len: ', len(drop.data)) self.glass.addDroplet(ew_drop) # 这里解决度函数切换过程不接收,解决进度包更新过程不接收 # if (self.feedback_ack_flag==False) or (self.feedback_ack_flag==True and ew_drop.func_id==1 and ew_drop.feedback_idx==self.feedback_idx-1): # self.real_drop_id += 1 # self.glass.addDroplet(ew_drop) # glass add drops # print("=============================================================") # print("除去度函数切换和进度包更新时收到的drop,Real_Recv_dropid : ", self.real_drop_id) # print("=============================================================") # self.feedback_send_done=False logging.info('=============================') logging.info('Decode Progress: ' + str(self.glass.chunksDone()) + '/' + str(self.glass.num_chunks)) logging.info('=============================') # 接收完成 if self.glass.isDone(): self.recv_done_flag = True self.t1 = time.time() logging.info('============Recv done===========') logging.info("VLC Feedback Fountain time elapsed:" + str(self.t1 - self.t0)) # 接收完成写入图像 img_data = self.glass.get_bits() os.mkdir(self.recv_dir) with open(os.path.join(self.recv_dir, "img_recv" + ".bmp"), 'wb') as f: f.write(img_data) self.send_recv_done_ack() # 接收完成返回ack # 记录吞吐量 self.cal_ttl() print('packet_id history: ', self.packid_save, len(self.packid_save)) print('packets per sec: ', self.packs_per_sec, len(self.packs_per_sec)) print('drop_id history: ', self.dropid_save, len(self.dropid_save)) print('drops per sec: ', self.drops_per_sec, len(self.drops_per_sec)) res = pd.DataFrame({ 'packet_id_history': self.packid_save, 'packets_per_sec': self.packs_per_sec, 'drop_id_history': self.dropid_save, 'drops_per_sec': self.drops_per_sec }) res.to_csv( ('data_save/Recv_ttl' + '_' + time.asctime().replace(' ', '_').replace(':', '_') + '.csv'), mode='a') # 反馈 n1 = round(0.8 * self.glass.num_chunks) n2 = 30 if self.drop_id >= n1 and self.recv_done_flag == False: if (self.drop_id - n1) % n2 == 0: process = self.glass.getProcess() # 用于添加反馈历史数据, 用于droplet参数,正确译码 self.chunk_process = process[0] self.glass.glass_process_history.append(self.chunk_process) # 用于实际反馈 process_bitmap = process[1] process_bits = bitarray.bitarray(process_bitmap) self.process_bytes = process_bits.tobytes() self.send_feedback() print("Feedback chunks: ", self.chunk_process) print("Feedback chunks num: ", len(self.chunk_process)) print("Feedback idx: ", self.feedback_idx) self.feedback_idx += 1 self.feedback_ack_flag = True self.feedback_send_done = True # if self.real_drop_id >= self.glass.num_chunks: # if (self.real_drop_id - self.glass.num_chunks)%10==0 and self.feedback_send_done==False: # self.chunk_process = self.glass.getProcess() # 用于返回进程包 # self.glass.glass_process_history.append(self.chunk_process) # 添加反馈历史数据,用于droplet参数,正确译码 # self.send_feedback() # print("Feedback chunks: ", self.chunk_process) # print("Feedback chunks num: ", len(self.chunk_process)) # print("Feedback idx: ", self.feedback_idx) # self.feedback_idx += 1 # self.feedback_ack_flag = True # self.feedback_send_done=True # 定时器线程每隔1s记录发包数,即吞吐量 def save_throughout_put(self): if (self.recv_done_flag == False): self.packid_save.append(self.packet_id) self.dropid_save.append(self.drop_id) self.valid_dropid_save.append(self.real_drop_id) self.creat_ttl_Timer() def creat_ttl_Timer(self): if (self.recv_done_flag == False): t = threading.Timer(1, self.save_throughout_put) t.start() # 计算吞吐量 def cal_ttl(self): idx = 0 while idx < len(self.packid_save): if idx == 0: self.packs_per_sec.append(self.packid_save[0]) else: self.packs_per_sec.append(self.packid_save[idx] - self.packid_save[idx - 1]) idx += 1 idx = 0 while idx < len(self.dropid_save): if idx == 0: self.drops_per_sec.append(self.dropid_save[0]) else: self.drops_per_sec.append(self.dropid_save[idx] - self.dropid_save[idx - 1]) idx += 1 def send_recv_done_ack(self): if self.recv_done_flag: ack = b'#$' acklen = len(ack) acksend = bytearray(ack) while (acklen < 239): acksend.insert(acklen, 0) acklen += 1 self.spiSend.xfer2(acksend) logging.info('Send fountain ACK done') logging.info('Recv Packets: : ' + str(self.packet_id)) logging.info('Recv drops: ' + str(self.drop_id)) def send_feedback(self): fb = b'$#' for chunk_id in self.chunk_process: chunk_id_bits = format(int(chunk_id), "016b") fb += bitarray.bitarray(chunk_id_bits).tobytes() fblen = len(fb) fbsend = bytearray(fb) while (fblen < 239): fbsend.insert(fblen, 0) fblen += 1 self.spiSend.xfer2(fbsend)
def sim_ber(): test_dir = os.path.join(SIM_PATH, 'sim_ber') if not os.path.exists(test_dir): os.mkdir(test_dir) chunk_size = 40 loop_num = 5 chunk_num = ceil(len(m) / float(chunk_size)) p1 = 0.4 ber = np.arange(0.0001, 0.015, 0.001) code_rate = [0] * len(ber) w1_size = 0.4 w1_done = [0] * len(ber) w2_done = [0] * len(ber) per_list = [0] * len(ber) raw_data_size = len(m) i = 0 for ber_ in tqdm(ber): print(heap) fountain = EW_Fountain(m, chunk_size=chunk_size, w1_size=w1_size, w1_pro=p1) for j in tqdm(range(loop_num)): glass = Glass(fountain.num_chunks) drop_id = 0 PER = 1 - (1 - ber_)**(chunk_size * 8) w1_done_t = 0 while (not glass.isDone()): # print(drop_id * float(chunk_size) / len(m)) drop_id += 1 a_drop = fountain.droplet() ew_drop = EW_Droplet(a_drop.data, a_drop.seed, a_drop.num_chunks, w1_size, w1_pro=p1) glass.addDroplet(ew_drop) if glass.is_w1_done(w1_size) and w1_done_t == 0: w1_done_t = drop_id del a_drop del ew_drop if (drop_id * chunk_size / raw_data_size > 50): print("_") code_rate[i] += chunk_size * drop_id / (1 - PER) w1_done[i] += w1_done_t * chunk_size / (1 - PER) w2_done[i] += drop_id * chunk_size / (1 - PER) per_list[i] = PER del glass del fountain i += 1 code_rate = [float(ii) / (len(m) * loop_num) for ii in code_rate] w1_done = [float(ii) / (len(m) * loop_num) for ii in w1_done] w2_done = [float(ii) / (len(m) * loop_num) for ii in w2_done] df_res = pd.DataFrame({ "ber": ber, "code_rate": code_rate, 'w1_done': w1_done, 'w2_done': w2_done, 'per': [1 - (1 - ii)**(8 * chunk_size) for ii in ber], 'loop_num': [loop_num for ii in ber], 'chunk_size': [chunk_size for ii in ber], 'p1': [p1 for ii in ber], 'chunk_num': [chunk_num for ii in ber], 'w1_size': [w1_size for ii in ber] }) res_file = os.path.join( test_dir, time.asctime().replace(' ', '_').replace( ':', '_')) + "_" + str(p1) + "_" + str(chunk_size) + '.csv' df_res.to_csv(res_file) print(df_res) return res_file
def sim_diff_psnr(): test_dir = os.path.join(SIM_PATH, 'sim_diff_psnr') if not os.path.exists(test_dir): os.mkdir(test_dir) res_file = os.path.join(test_dir, time.asctime().replace(' ', '_').replace( ':', '_')) + '.csv' need_lest = 79 packet_ceil = 631 deli_rate = pkl.load(open(os.path.join(SIM_PATH, 'deil.pkl'), 'rb')) loop_num = 1000 m = ' ' * need_lest p1_list = list(np.arange(0.1, 0.9, 0.1)) w1_list = list(np.arange(0.1, 0.9, 0.1)) res_size = len(p1_list) * len(w1_list) res_w1 = [0] * res_size for i in range(res_size): res_w1[i] = w1_list[int(i / len(p1_list))] res = pd.DataFrame({ "w1": res_w1, 'p1': p1_list * len(w1_list), # 'w1_done' : [0] * res_size, # "all_done": [0] * res_size }) w1_done_tmp = [0] * res_size all_done_tmp = [0] * res_size i = 0 for w1 in tqdm(w1_list): j = 0 for p1 in tqdm(p1_list): all_done = 0 res_index = i * len(p1_list) + j for loop in tqdm(range(loop_num)): fountain = EW_Fountain(m, chunk_size=1, w1_size=w1, w1_pro=p1) glass = Glass(fountain.num_chunks) w1_done = 0 for drop_id in range(packet_ceil): a_drop = fountain.droplet() ew_drop = EW_Droplet(a_drop.data, a_drop.seed, a_drop.num_chunks, w1, p1) glass.addDroplet(ew_drop) if glass.is_w1_done(w1) and w1_done == 0: w1_done_tmp[res_index] += drop_id w1_done = 1 # print("w1 done at {}".format(drop_id)) elif glass.isDone(): # print("all done at {}".format(drop_id)) all_done_tmp[res_index] += drop_id break w1_done_tmp[res_index] = w1_done_tmp[res_index] / float(loop_num) all_done_tmp[res_index] = all_done_tmp[res_index] / float(loop_num) j += 1 i += 1 res['w1_done'] = w1_done_tmp res['all_done'] = all_done_tmp res = res[['w1', 'p1', 'w1_done', 'all_done']] print(res) res.to_csv(res_file)
def sim_p1(): test_dir = os.path.join(SIM_PATH, 'sim_p1') res_file = os.path.join(test_dir, time.asctime().replace(' ', '_').replace( ':', '_')) + '.csv' step = 0.05 floor = 0.3 ceiling = 0.7 p1_list = list(np.arange(floor, ceiling, step)) p1_list.reverse() code_rate = [0] * len(p1_list) w1_size = 0.5 w1_done = [0] * len(p1_list) w2_done = [0] * len(p1_list) per_list = [0] * len(p1_list) chunk_size = 255 loop_num = 50 chunk_num = ceil(len(m) / float(chunk_size)) BER = 0.0001 i = 0 for p1 in tqdm(p1_list): for j in tqdm(range(loop_num)): fountain = EW_Fountain(m, chunk_size=chunk_size, w1_size=w1_size, w1_pro=p1) glass = Glass(fountain.num_chunks) drop_id = 0 PER = 1 - (1 - BER)**(chunk_size * 8) w1_done_t = 0 while not glass.isDone(): drop_id += 1 a_drop = fountain.droplet() ew_drop = EW_Droplet(a_drop.data, a_drop.seed, a_drop.num_chunks, w1_size, w1_pro=p1) glass.addDroplet(ew_drop) if glass.is_w1_done(w1_size) and w1_done_t == 0: w1_done_t = drop_id del a_drop del ew_drop code_rate[i] += chunk_size * drop_id / (1 - PER) w1_done[i] += w1_done_t * chunk_size / (1 - PER) w2_done[i] += drop_id * chunk_size / (1 - PER) per_list[i] = PER del fountain del glass i += 1 code_rate = [float(ii) / (len(m) * loop_num) for ii in code_rate] w1_done = [float(ii) / (len(m) * loop_num) for ii in w1_done] w2_done = [float(ii) / (len(m) * loop_num) for ii in w2_done] df_res = pd.DataFrame({ "p1": p1_list, "code_rate": code_rate, 'w1_done': w1_done, 'w2_done': w2_done, 'per': per_list, 'loop_num': [loop_num for ii in p1_list], 'chunk_size': [chunk_size for ii in p1_list], 'chunk_num': [chunk_num for ii in p1_list], 'w1_size': [w1_size for ii in p1_list] }) df_res.to_csv(res_file) print(df_res) return res_file
class Receiver: def __init__( self, bus, device, ): self.spiRecv = spidev.SpiDev() self.spiRecv.open(bus, device) self.spiRecv.max_speed_hz = 6250000 #976000 self.spiRecv.mode = 0b00 self.spiSend = spidev.SpiDev() self.spiSend.open(bus, 0) self.spiSend.max_speed_hz = 6250000 #976000 self.spiSend.mode = 0b00 spi_init() self.drop_id = 0 self.glass = Glass(0) self.chunk_size = 0 self.current_recv_bits_len = 0 self.recv_done_flag = False self.data_rec = "" '''LT喷泉码接收解码部分''' def begin_to_catch(self): a_drop_bytes = self.catch_a_drop_spi() # bytes if a_drop_bytes is not None: check_data = recv_check(a_drop_bytes) if not check_data == None: self.drop_id += 1 print("recv drops id : ", self.drop_id) self.drop_byte_size = len(check_data) self.add_a_drop(check_data) # bytes --- drop --- bits def catch_a_drop_spi(self): if GPIO.input(25): spi_recv = self.spiRecv.readbytes(239) rec_bytes = bytes(spi_recv) frame_len = len(rec_bytes) print("framelen: ", frame_len) while (rec_bytes[frame_len - 1] == 0): frame_len = frame_len - 1 rec_bytes = rec_bytes[:frame_len] print("droplen: ", frame_len) self.data_rec = rec_bytes if self.data_rec[0:2] == b'##' and self.data_rec[ frame_len - 2:frame_len] == b'$$': data_array = bytearray(self.data_rec) data_array.pop(0) data_array.pop(0) data_array.pop() data_array.pop() a = len(data_array) print('drop len(crc) :', a) return bytes(data_array) else: print(self.data_rec[0:2], b'##') print(self.data_rec[frame_len - 2:frame_len], b'$$') print('Wrong receive frame !') def add_a_drop(self, d_byte): drop = self.glass.droplet_from_Bytes(d_byte) # drop print('drop data len: ', len(drop.data)) if self.glass.num_chunks == 0: print('init num_chunks : ', drop.num_chunks) self.glass = Glass(drop.num_chunks) # 初始化接收glass self.chunk_size = len(drop.data) self.glass.addDroplet(drop) # glass add drops logging.info('current chunks') logging.info( [ii if ii == None else '++++' for ii in self.glass.chunks]) logging.info('=============================') if self.glass.isDone(): self.recv_done_flag = True logging.info('============Recv done===========') logging.info(self.glass.getString()) self.send_recv_done_ack() # 接收完成返回ack def send_recv_done_ack(self): if self.recv_done_flag: ack = b'#$' acklen = len(ack) acksend = bytearray(ack) while (acklen < 239): acksend.insert(acklen, 0) acklen += 1 self.spiSend.xfer2(acksend) logging.info('Send fountain ACK done')
class Receiver: def __init__( self, bus, device, ): self.spiRecv = spidev.SpiDev() self.spiRecv.open(bus, device) self.spiRecv.max_speed_hz = 6250000 #976000 self.spiRecv.mode = 0b00 self.spiSend = spidev.SpiDev() self.spiSend.open(bus, 0) self.spiSend.max_speed_hz = 6250000 #976000 self.spiSend.mode = 0b00 spi_init() self.pack_id = 0 self.drop_id = 0 self.wrong_frame = 0 self.wrong_checksum = 0 self.glass = Glass(0) self.chunk_size = 0 self.current_recv_bits_len = 0 self.recv_done_flag = False self.data_rec = "" self.recv_dir = os.path.join( RECV_PATH, time.asctime().replace(' ', '_').replace(':', '_')) '''LT喷泉码接收解码部分''' def begin_to_catch(self): a_drop_bytes = self.catch_a_drop_spi() # bytes if a_drop_bytes is not None: self.pack_id += 1 if len(a_drop_bytes) > 0: check_data = recv_check(a_drop_bytes) if not check_data == None: self.drop_byte_size = len(check_data) self.add_a_drop(check_data) # bytes --- drop --- bits else: self.wrong_checksum += 1 def catch_a_drop_spi(self): if GPIO.input(25): spi_recv = self.spiRecv.readbytes(239) rec_bytes = bytes(spi_recv) frame_len = len(rec_bytes) print("framelen: ", frame_len) # print(rec_bytes) if (frame_len > 1): while (rec_bytes[frame_len - 1] == 0 and frame_len >= 1): frame_len = frame_len - 1 rec_bytes = rec_bytes[:frame_len] print("droplen: ", frame_len) self.data_rec = rec_bytes if self.data_rec[0:2] == b'##' and self.data_rec[ frame_len - 2:frame_len] == b'$$': data_array = bytearray(self.data_rec) data_array.pop(0) data_array.pop(0) data_array.pop() data_array.pop() return bytes(data_array) else: self.wrong_frame += 1 print(self.data_rec[0:2], b'##') print(self.data_rec[frame_len - 2:frame_len], b'$$') print('Wrong receive frame !') def add_a_drop(self, d_byte): self.drop_id += 1 drop = self.glass.droplet_from_Bytes(d_byte) # drop # print('drop data len: ', len(drop.data)) if self.glass.num_chunks == 0: print('init num_chunks : ', drop.num_chunks) self.glass = Glass(drop.num_chunks) # 初始化接收glass self.chunk_size = len(drop.data) self.glass.addDroplet(drop) # glass add drops # logging.info('current chunks') # logging.error([ii if ii == None else '++++' for ii in self.glass.chunks]) # logging.info('=============================') if self.glass.isDone(): self.recv_done_flag = True logging.info('============Recv done===========') logging.info('Send fountain ACK done') logging.info('Recv packs: ' + str(self.pack_id)) logging.info('Recv drops: ' + str(self.drop_id)) # 接收完成写入图像 # img_data = self.glass.get_bits() # os.mkdir(self.recv_dir) # with open(os.path.join(self.recv_dir, "img_recv" + ".jpg"), 'wb') as f: # f.write(img_data) # self.send_recv_done_ack() # 接收完成返回ack def send_recv_done_ack(self): if self.recv_done_flag: ack = b'#$' acklen = len(ack) acksend = bytearray(ack) while (acklen < 239): acksend.insert(acklen, 0) acklen += 1 self.spiSend.xfer2(acksend) logging.info('Send fountain ACK done') # logging.info('Recv packs: ' + str(self.pack_id)) logging.info('Recv drops: ' + str(self.drop_id))
class Receiver: def __init__( self, bus, device, port, baudrate, timeout, ): self.spiRecv = spidev.SpiDev() self.spiRecv.open(bus, device) self.spiRecv.max_speed_hz = 6250000 #976000 self.spiRecv.mode = 0b00 self.spiSend = spidev.SpiDev() self.spiSend.open(bus, 0) self.spiSend.max_speed_hz = 6250000 #976000 self.spiSend.mode = 0b00 # 串口和spi初始化 spi_init() self.port = serial.Serial(port, baudrate) self.pack_id = 0 self.drop_id = 0 self.glass = Glass(0) self.chunk_size = 0 self.recv_done_flag = False self.feedback_ack_flag = False self.chunk_process = [] self.feedback_idx = 0 self.data_rec = "" self.recv_dir = os.path.join( RECV_PATH, time.asctime().replace(' ', '_').replace(':', '_')) self.t0 = 0 self.t0_start = False self.t1 = 0 self.process_bytes = b'' '''LT喷泉码接收解码部分''' def begin_to_catch(self): a_drop_bytes = self.catch_a_drop_spi() # bytes if a_drop_bytes is not None: # 从接收到第一个包开始计时 if self.t0_start == False: self.t0 = time.time() self.t0_start = True self.pack_id += 1 print("Recv Packet_id : ", self.pack_id) if len(a_drop_bytes) > 0: check_data = recv_check(a_drop_bytes) if not check_data == None: self.drop_byte_size = len(check_data) self.add_a_drop(check_data) def catch_a_drop_spi(self): if GPIO.input(25): spi_recv = self.spiRecv.readbytes(239) rec_bytes = bytes(spi_recv) frame_len = len(rec_bytes) if (frame_len > 1): while (rec_bytes[frame_len - 1] == 0 and frame_len >= 1): frame_len = frame_len - 1 rec_bytes = rec_bytes[:frame_len] self.data_rec = rec_bytes if self.data_rec[0:2] == b'##' and self.data_rec[ frame_len - 2:frame_len] == b'$$': data_array = bytearray(self.data_rec) data_array.pop(0) data_array.pop(0) data_array.pop() data_array.pop() return bytes(data_array) else: print(self.data_rec) print('Wrong receive frame !') def add_a_drop(self, d_byte): self.drop_id += 1 print("====================") print("Recv drop_id : ", self.drop_id) print("====================") drop = self.glass.droplet_from_Bytes(d_byte) # drop if self.glass.num_chunks == 0: self.glass = Glass(drop.num_chunks) # 初始化接收glass self.chunk_size = len(drop.data) #若为ew,则需要将drop转为ewdrop,两个drop里译码方式不一样 ew_drop = EW_Droplet(drop.data, drop.seed, drop.num_chunks, drop.process, drop.func_id, drop.feedback_idx) self.glass.addDroplet(ew_drop) # glass add drops logging.info('=============================') logging.info('Decode Progress: ' + str(self.glass.chunksDone()) + '/' + str(self.glass.num_chunks)) logging.info('=============================') # 接收完成 if self.glass.isDone(): self.t1 = time.time() self.recv_done_flag = True # # 接收完成写入图像 # img_data = self.glass.get_bits() # os.mkdir(self.recv_dir) # with open(os.path.join(self.recv_dir, "img_recv" + ".bmp"), 'wb') as f: # f.write(img_data) t1 = threading.Timer(2.6, self.send_recv_done_ack) t1.start() # self.send_recv_done_ack() # 接收完成返回ack logging.info('============Recv done===========') logging.info('Send Sonic Fountain ACK done') logging.info('Recv packets: ' + str(self.drop_id)) logging.info('Recv drops: ' + str(self.drop_id)) logging.info("Sonic Feedback Fountain time elapsed:" + str(self.t1 - self.t0)) # 接收到K个数据包之后 n1 = round(0.8 * self.glass.num_chunks) n2 = 30 if self.drop_id >= n1 and self.recv_done_flag == False: if (self.drop_id - n1) % n2 == 0: process = self.glass.getProcess() # 用于添加反馈历史数据, 用于droplet参数,正确译码 self.chunk_process = process[0] self.glass.glass_process_history.append(self.chunk_process) # 用于实际反馈 process_bitmap = process[1] process_bits = bitarray.bitarray(process_bitmap) self.process_bytes = process_bits.tobytes() t = threading.Timer(2.6, self.send_feedback) t.start() print(self.process_bytes) print("Feedback chunks: ", self.chunk_process) print("Feedback chunks num: ", len(self.chunk_process)) print("Feedback idx: ", self.feedback_idx) self.feedback_idx += 1 def send_recv_done_ack(self): if self.recv_done_flag: ack = b'#$\r\n' acksend = bytearray(ack) self.port.write(acksend) self.port.flushOutput() # 用定时器线程反馈仿真修改 def send_feedback(self): fb = b'$#' + self.process_bytes self.port.write(fb) self.port.flushOutput()