Introduccion:
En la parte uno de esta entrada ISIS Cubesat Telemetry (Part 1) explicamos brevemente algunas particularidades de la telemetría en el área satelital. Encontramos un XML que describía parcialmente los paquetes que llegan del satelite por TCP/IP y decimos parcialmente porque en la practica si intentamos desempaquetar la trama utilizando unicamente el XML el proceso falla.
La razón es que ese XML describe el paquete (packet) de una trama mayor que viene dada de la siguiente manera.
En las siguientes lineas vamos a desarmar completamente la trama hasta llegar a las variables de telemetria.
Primero establecemos hasta donde nos es posible posición y tamaño de las cosas. Como se observa en la tabla 7.1 existen campos de tamaño variable (Ejemplo: modulation name con tamaño indicado por modulation name length) que impiden presetear todo de antemano.
Luego en un bucle infinito desarmamos los paquetes que van llegando hasta llegar al payload que es lo que nos interesa. Esta variable es la que en futuras entradas vamos a desarmar en función del xml de configuración. Por lo pronto el siguiente código recibe en un bucle infinito la trama (chunk) del socket y la desarma hasta llegar al payload, el código tiene una breve descripción de lo que hace antes de cada linea y se puede observar que el mismo es no bloqueante porque por el mismo canal debe enviarse los comandos....
Primero establecemos hasta donde nos es posible posición y tamaño de las cosas. Como se observa en la tabla 7.1 existen campos de tamaño variable (Ejemplo: modulation name con tamaño indicado por modulation name length) que impiden presetear todo de antemano.
PosFrameCommand = 0 LenFrameCommand = 1 PosFrameLen = PosFrameCommand+LenFrameCommand LenFrameLen = 4 PosDataRate = PosFrameLen+LenFrameLen LenDataRate = 4 PosModuluationNameLen = PosDataRate+LenDataRate LenModuluationNameLen = 1 PosModulationName = PosModuluationNameLen+LenModuluationNameLen LenModulationName = 0 PosRSSI = PosModulationName+LenModulationName LenRSSI = 8 PosFrequency = PosRSSI+LenRSSI LenFrequency = 8 PosPktLen = PosFrequency+LenFrequency LenPktLen = 2
Luego en un bucle infinito desarmamos los paquetes que van llegando hasta llegar al payload que es lo que nos interesa. Esta variable es la que en futuras entradas vamos a desarmar en función del xml de configuración. Por lo pronto el siguiente código recibe en un bucle infinito la trama (chunk) del socket y la desarma hasta llegar al payload, el código tiene una breve descripción de lo que hace antes de cada linea y se puede observar que el mismo es no bloqueante porque por el mismo canal debe enviarse los comandos....
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.connect( (uhfServerIp, int(uhfServerPort)) ) print("Successfully connection to..", uhfServerPort) while True: try: """ Establezco un timeout para la bajada, con o sin bajada los comandos deben ser enviados """ s.settimeout(5.0) """ Me quedo esperando recibir informacion del socket (IPC) """ chunk = s.recv(int(BUFFER_SIZE)) unconnectionLimit = 0 """ Buena o mala la telemetria fue recibida, reseteo el watchdog """ wd.reset() """ Si recibo telemetria, defenitivamente estoy en contacto """ sat.setInContact(True) """ Si la informacion es una trama de bits completa la proceso """ if chunk == b'': raise RuntimeError("socket connection broken") else: os.system('cls||clear') print(bcolors.OKGREEN+"--------------------Data Received-------------------"+bcolors.OKGREEN) print("Data length:", len(chunk)) #Me guardo el crudo tal cual llego antes de procesarlo, la tabla donde se guarda es UHFRawData data = UHFRawData() data.source = source data.data = chunk data.processed = False data.save() framecommand = unpack("<B",chunk[PosFrameCommand:PosFrameCommand+LenFrameCommand])[0] frameLength = unpack("<I",chunk[PosFrameLen:PosFrameLen+LenFrameLen]) datarate = unpack("<I",chunk[PosDataRate:PosDataRate+LenDataRate]) modulationnamelen = (unpack("<B",chunk[PosModuluationNameLen:PosModuluationNameLen+LenModuluationNameLen]))[0] modulationname = chunk[PosModulationName:PosModulationName+modulationnamelen] PosRSSI = PosModulationName+modulationnamelen rssi = unpack("<d", chunk[PosRSSI:PosRSSI+LenRSSI]) PosFrequency = PosRSSI+LenRSSI freq = unpack("<d", chunk[PosFrequency:PosFrequency+LenFrequency]) PosPktLen = PosFrequency+LenFrequency pktLen = unpack("<H", chunk[PosPktLen:PosPktLen+LenPktLen]) PosUtcTime = PosPktLen+pktLen[0] LenUtcTime = 4 PosPayload = PosPktLen+int(LenPktLen) ax25 = chunk[PosPayload:PosPayload+pktLen[0]] destination = ax25[0:7] asource = ax25[7:7+7] control = ax25[7+7:7+7+1] protocol = ax25[7+7+1:7+7+1+1] vardataoffset = 7+7+1+1 payload = ax25[ vardataoffset: ] pn = unpack("<H", payload[1:3]) print("Packet number:", pn) frameTypeId = payload[0] dl = DownlinkFrame() dl.frameCommand = framecommand dl.frameLength = frameLength[0] dl.dataRate = datarate[0] dl.modulationName = str(modulationname) dl.rssi = rssi[0] dl.frequency = freq[0] dl.packetLength = pktLen[0] dl.satellite = sat dl.ax25Destination = "Pending"#destination.decode("utf-8") dl.ax25Source = "Pending"#asource.decode("utf-8") dl.ax25Protocol = "Pending"#protocol.decode("utf-8") dl.ax25Control = "Pending"#control.decode("utf-8") dl.packetNumber = pn[0] dl.frameTypeId = frameTypeId
No hay comentarios:
Publicar un comentario