diff --git a/Makefile b/Makefile index 72a1857a58b..2dec3a84c46 100644 --- a/Makefile +++ b/Makefile @@ -78,6 +78,11 @@ LOGALIZER=sw/logalizer SUBDIRS = $(PPRZCENTER) $(MISC) $(LOGALIZER) sw/tools +# +# Communication protocol version +# +PPRZLINK_LIB_VERSION ?= 1.0 + # # xml files used as input for header generation # @@ -91,7 +96,7 @@ XSENS_XML = $(CONF)/xsens_MTi-G.xml # generated header files # PPRZLINK_DIR=sw/ext/pprzlink -PPRZLINK_INSTALL=$(PAPARAZZI_HOME)/var/lib/ocaml +PPRZLINK_INSTALL=$(PAPARAZZI_HOME)/var/lib MESSAGES_INSTALL=$(PAPARAZZI_HOME)/var UBX_PROTOCOL_H=$(STATICINCLUDE)/ubx_protocol.h MTK_PROTOCOL_H=$(STATICINCLUDE)/mtk_protocol.h @@ -137,7 +142,7 @@ static: cockpit tmtc generators sim_static joystick static_h libpprzlink: $(MAKE) -C $(EXT) pprzlink.update - $(Q)Q=$(Q) DESTDIR=$(PPRZLINK_INSTALL) $(MAKE) -C $(PPRZLINK_DIR) libpprzlink-install + $(Q)Q=$(Q) DESTDIR=$(PPRZLINK_INSTALL) PPRZLINK_LIB_VERSION=${PPRZLINK_LIB_VERSION} $(MAKE) -C $(PPRZLINK_DIR) libpprzlink-install libpprz: libpprzlink _save_build_version $(MAKE) -C $(LIB)/ocaml @@ -191,10 +196,10 @@ pprzlink_protocol : $(Q)test -d $(STATICLIB) || mkdir -p $(STATICLIB) ifeq ("$(wildcard $(CUSTOM_MESSAGES_XML))","") @echo GENERATE $@ with default messages - $(Q)Q=$(Q) MESSAGES_INSTALL=$(MESSAGES_INSTALL) VALIDATE_XML=FALSE $(MAKE) -C $(PPRZLINK_DIR) pymessages + $(Q)Q=$(Q) MESSAGES_INSTALL=$(MESSAGES_INSTALL) VALIDATE_XML=FALSE PPRZLINK_LIB_VERSION=${PPRZLINK_LIB_VERSION} $(MAKE) -C $(PPRZLINK_DIR) pymessages else @echo GENERATE $@ with custome messages from $(CUSTOM_MESSAGES_XML) - $(Q)Q=$(Q) MESSAGES_XML=$(CUSTOM_MESSAGES_XML) MESSAGES_INSTALL=$(MESSAGES_INSTALL) $(MAKE) -C $(PPRZLINK_DIR) pymessages + $(Q)Q=$(Q) MESSAGES_XML=$(CUSTOM_MESSAGES_XML) MESSAGES_INSTALL=$(MESSAGES_INSTALL) PPRZLINK_LIB_VERSION=${PPRZLINK_LIB_VERSION} $(MAKE) -C $(PPRZLINK_DIR) pymessages endif diff --git a/sw/airborne/subsystems/datalink/datalink.c b/sw/airborne/subsystems/datalink/datalink.c index 3efde33e040..2638085cd09 100644 --- a/sw/airborne/subsystems/datalink/datalink.c +++ b/sw/airborne/subsystems/datalink/datalink.c @@ -66,81 +66,121 @@ void dl_parse_msg(struct link_device *dev, struct transport_tx *trans, uint8_t * } } } else { - /* parse telemetry messages coming from ground station */ - switch (msg_id) { - case DL_PING: { - pprz_msg_send_PONG(trans, dev, AC_ID); - } - break; - - case DL_SETTING : { - if (DL_SETTING_ac_id(buf) != AC_ID) { break; } - uint8_t i = DL_SETTING_index(buf); - float var = DL_SETTING_value(buf); - DlSetting(i, var); - pprz_msg_send_DL_VALUE(trans, dev, AC_ID, &i, &var); - } - break; +#if PPRZLINK_DEFAULT_VER == 2 + // Check that the message is really a datalink message + if (pprzlink_get_msg_class_id(buf) == DL_datalink_CLASS_ID) { +#endif + /* parse datalink messages coming from ground station */ + switch (msg_id) { + case DL_PING: { +#if PPRZLINK_DEFAULT_VER == 2 + // Reply to the sender of the message + struct pprzlink_msg msg; + msg.trans = trans; + msg.dev = dev; + msg.sender_id = AC_ID; + msg.receiver_id = sender_id; + msg.component_id = 0; + pprzlink_msg_send_PONG(&msg); +#else + pprz_msg_send_PONG(trans, dev, AC_ID); +#endif + } + break; - case DL_GET_SETTING : { - if (DL_GET_SETTING_ac_id(buf) != AC_ID) { break; } - uint8_t i = DL_GET_SETTING_index(buf); - float val = settings_get_value(i); - pprz_msg_send_DL_VALUE(trans, dev, AC_ID, &i, &val); - } - break; + case DL_SETTING : { + if (DL_SETTING_ac_id(buf) != AC_ID) { break; } + uint8_t i = DL_SETTING_index(buf); + float var = DL_SETTING_value(buf); + DlSetting(i, var); +#if PPRZLINK_DEFAULT_VER == 2 + // Reply to the sender of the message + struct pprzlink_msg msg; + msg.trans = trans; + msg.dev = dev; + msg.sender_id = AC_ID; + msg.receiver_id = sender_id; + msg.component_id = 0; + pprzlink_msg_send_DL_VALUE(&msg, &i, &var); +#else + pprz_msg_send_DL_VALUE(trans, dev, AC_ID, &i, &var); +#endif + } + break; -#ifdef RADIO_CONTROL_TYPE_DATALINK - case DL_RC_3CH : -#ifdef RADIO_CONTROL_DATALINK_LED - LED_TOGGLE(RADIO_CONTROL_DATALINK_LED); + case DL_GET_SETTING : { + if (DL_GET_SETTING_ac_id(buf) != AC_ID) { break; } + uint8_t i = DL_GET_SETTING_index(buf); + float val = settings_get_value(i); +#if PPRZLINK_DEFAULT_VER == 2 + // Reply to the sender of the message + struct pprzlink_msg msg; + msg.trans = trans; + msg.dev = dev; + msg.sender_id = AC_ID; + msg.receiver_id = sender_id; + msg.component_id = 0; + pprzlink_msg_send_DL_VALUE(&msg, &i, &val); +#else + pprz_msg_send_DL_VALUE(trans, dev, AC_ID, &i, &val); #endif - parse_rc_3ch_datalink( - DL_RC_3CH_throttle_mode(buf), - DL_RC_3CH_roll(buf), - DL_RC_3CH_pitch(buf)); + } break; - case DL_RC_4CH : - if (DL_RC_4CH_ac_id(buf) == AC_ID) { + +#ifdef RADIO_CONTROL_TYPE_DATALINK + case DL_RC_3CH : #ifdef RADIO_CONTROL_DATALINK_LED LED_TOGGLE(RADIO_CONTROL_DATALINK_LED); #endif - parse_rc_4ch_datalink(DL_RC_4CH_mode(buf), - DL_RC_4CH_throttle(buf), - DL_RC_4CH_roll(buf), - DL_RC_4CH_pitch(buf), - DL_RC_4CH_yaw(buf)); - } - break; + parse_rc_3ch_datalink( + DL_RC_3CH_throttle_mode(buf), + DL_RC_3CH_roll(buf), + DL_RC_3CH_pitch(buf)); + break; + case DL_RC_4CH : + if (DL_RC_4CH_ac_id(buf) == AC_ID) { +#ifdef RADIO_CONTROL_DATALINK_LED + LED_TOGGLE(RADIO_CONTROL_DATALINK_LED); +#endif + parse_rc_4ch_datalink(DL_RC_4CH_mode(buf), + DL_RC_4CH_throttle(buf), + DL_RC_4CH_roll(buf), + DL_RC_4CH_pitch(buf), + DL_RC_4CH_yaw(buf)); + } + break; #endif // RADIO_CONTROL_TYPE_DATALINK #if USE_GPS - case DL_GPS_INJECT : { - // Check if the GPS is for this AC - if (DL_GPS_INJECT_ac_id(buf) != AC_ID) { break; } - - // GPS parse data - gps_inject_data( - DL_GPS_INJECT_packet_id(buf), - DL_GPS_INJECT_data_length(buf), - DL_GPS_INJECT_data(buf) - ); - } - break; + case DL_GPS_INJECT : { + // Check if the GPS is for this AC + if (DL_GPS_INJECT_ac_id(buf) != AC_ID) { break; } + + // GPS parse data + gps_inject_data( + DL_GPS_INJECT_packet_id(buf), + DL_GPS_INJECT_data_length(buf), + DL_GPS_INJECT_data(buf) + ); + } + break; #if USE_GPS_UBX_RTCM - case DL_RTCM_INJECT : { - // GPS parse data - gps_inject_data(DL_RTCM_INJECT_packet_id(buf), - DL_RTCM_INJECT_data_length(buf), - DL_RTCM_INJECT_data(buf)); - } - break; + case DL_RTCM_INJECT : { + // GPS parse data + gps_inject_data(DL_RTCM_INJECT_packet_id(buf), + DL_RTCM_INJECT_data_length(buf), + DL_RTCM_INJECT_data(buf)); + } + break; #endif // USE_GPS_UBX_RTCM #endif // USE_GPS - default: - break; + default: + break; + } +#if PPRZLINK_DEFAULT_VER == 2 } +#endif } /* Parse firmware specific datalink */ firmware_parse_msg(dev, trans, buf); diff --git a/sw/airborne/subsystems/datalink/datalink.h b/sw/airborne/subsystems/datalink/datalink.h index 1c795b86220..35323d96b60 100644 --- a/sw/airborne/subsystems/datalink/datalink.h +++ b/sw/airborne/subsystems/datalink/datalink.h @@ -36,10 +36,6 @@ #include "std.h" #include "pprzlink/dl_protocol.h" -/* Message id helpers */ -#define SenderIdOfPprzMsg(x) (x[0]) -#define IdOfPprzMsg(x) (x[1]) - /** Datalink kinds */ #define PPRZ 1 #define XBEE 2 diff --git a/sw/ext/pprzlink b/sw/ext/pprzlink index 2e0309c3e34..42e0492bf17 160000 --- a/sw/ext/pprzlink +++ b/sw/ext/pprzlink @@ -1 +1 @@ -Subproject commit 2e0309c3e342c8f41e7c6ea92450a245749be90f +Subproject commit 42e0492bf177605602d943642b64f686993b6e02 diff --git a/sw/ground_segment/python/udp_link/udp_link.py b/sw/ground_segment/python/udp_link/udp_link.py index 56c6d9b872f..8d2514f55b5 100755 --- a/sw/ground_segment/python/udp_link/udp_link.py +++ b/sw/ground_segment/python/udp_link/udp_link.py @@ -1,33 +1,28 @@ #!/usr/bin/env python -from ivy.std_api import * -import socket -import struct import os -import logging import sys -import threading -import time # if PAPARAZZI_SRC not set, then assume the tree containing this # file is a reasonable substitute -PPRZ_SRC = os.getenv("PAPARAZZI_SRC", os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), - '../../../../'))) -sys.path.append(PPRZ_SRC + "/sw/lib/python") -sys.path.append(PPRZ_SRC + "/sw/ext/pprzlink/lib/v1.0/python") +PAPARAZZI_HOME = os.getenv("PAPARAZZI_HOME", os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)),'../../../../'))) +sys.path.append(PAPARAZZI_HOME + "/var/lib/python") -import pprz_env -from pprzlink import messages_xml_map - -PING_PERIOD = 5.0 -STATUS_PERIOD = 1.0 +from ivy.std_api import * +import threading +import time -STX = 0x99 -STX_TS = 0x98 +import pprzlink.udp +import pprzlink.ivy +import pprzlink.messages_xml_map as messages_xml_map +import pprzlink.message as message -DATALINK_PORT = 4243 -DOWNLINK_PORT = 4242 +DEFAULT_BROADCAST= "127.255.255.255" +REPEAT="Repeat" +IP_BCAST="IPBcast" +PING_PERIOD = 5.0 +STATUS_PERIOD = 1.0 class DownLinkStatus(): def __init__(self, ac_id, address): @@ -35,121 +30,118 @@ def __init__(self, ac_id, address): self.address = address self.rx_bytes = 0 self.rx_msgs = 0 + self.tx_msgs = 0 self.run_time = 0 self.last_rx_bytes = 0 self.last_rx_msgs = 0 + self.last_msg_time = 0 self.last_ping_time = 0 self.last_pong_time = 0 - -class IvyUdpLink(): - def __init__(self): - self.InitIvy() - self.ivy_id = 0 - self.status_timer = threading.Timer(STATUS_PERIOD, self.sendStatus) - self.ping_timer = threading.Timer(STATUS_PERIOD, self.sendPing) +class UDPLink: + def __init__(self,opts): + messages_xml_map.parse_messages() + self.run_event = threading.Event() + self.uplink_port = opts.uplink_port + self.downlink_port = opts.downlink_port + self.udp = pprzlink.udp.UdpMessagesInterface(self.proccess_downlink_msg, False, self.uplink_port, self.downlink_port) + self.ivy = pprzlink.ivy.IvyMessagesInterface("UDPLink", True, False, opts.bus) self.ac_downlink_status = {} self.rx_err = 0 + self.status_timer = threading.Timer(STATUS_PERIOD, self.sendStatus) + self.ping_timer = threading.Timer(PING_PERIOD, self.sendPing) + self.bcast_method = opts.broadcast_method + self.bcast_addr = opts.broadcast_address - messages_xml_map.parse_messages() - self.data_types = {'float': ['f', 4], - 'uint8': ['B', 1], - 'uint16': ['H', 2], - 'uint32': ['L', 4], - 'int8': ['b', 1], - 'int16': ['h', 2], - 'int32': ['l', 4] - } - - def __del__(self): - self.stop() - - def stop(self): - self.status_timer.cancel() - self.ping_timer.cancel() - IvyUnBindMsg(self.ivy_id) - IvyStop() + def updateStatus(self, ac_id, length, address, isPong): + if not self.ac_downlink_status.has_key(ac_id): + self.ac_downlink_status[ac_id] = DownLinkStatus(ac_id, address) + self.ac_downlink_status[ac_id].rx_msgs += 1 + self.ac_downlink_status[ac_id].rx_bytes += length + self.ac_downlink_status[ac_id].last_msg_time = time.time() + if isPong: + self.ac_downlink_status[ac_id].last_pong_time = time.time() - self.ac_downlink_status[ac_id].last_ping_time + + def proccess_downlink_msg(self,sender,address,msg,length,receiver_id=None, component_id=None): + if self.run_event.is_set(): + # print("new message from %i (%s) [%d Bytes]: %s" % (sender, address, length, msg)) + self.ivy.send(msg,sender,receiver_id,component_id) + self.updateStatus(sender, length, address,msg.name == "PONG") + + def proccess_uplink_msg(self,ac_id,msg): + # print ('New IVY message to %s : %s' % (ac_id,msg)) + if msg.broadcasted: + if self.bcast_method==IP_BCAST: + self.udp.send(msg,0,(self.bcast_addr,self.uplink_port)) + else: + for dest in self.ac_downlink_status.keys(): + self.udp.send(msg, 0, (self.ac_downlink_status[dest].address[0], self.uplink_port)) + self.ac_downlink_status[dest].tx_msgs += 1 + else: + if isinstance(ac_id,str): + ac_id = int(ac_id) + # Only send message if the ac is known + if self.ac_downlink_status.has_key(ac_id): + self.udp.send(msg,0,(self.ac_downlink_status[ac_id].address[0],self.uplink_port),ac_id) + self.ac_downlink_status[ac_id].tx_msgs+=1 + else: + print ('Message for unknown ac %d' % ac_id) - def Unpack(self, data_fields, type, start, length): - return struct.unpack(type, "".join(data_fields[start:start + length]))[0] + def initial_ivy_binds(self): + # Subscribe to all datalink messages + messages_datalink = messages_xml_map.get_msgs("datalink") + for msg in messages_datalink: + self.ivy.subscribe(self.proccess_uplink_msg, message.PprzMessage("datalink", msg)) - def InitIvy(self): - # initialising the bus - IvyInit("Link", # application name for Ivy - "READY", # ready message - 0, # main loop is local (ie. using IvyMainloop) - lambda x, y: y, # handler called on connection/deconnection - lambda x, y: y # handler called when a diemessage is received - ) + def run(self): + print ('Starting UDPLink for protocol version %s' % (messages_xml_map.PROTOCOL_VERSION)) + self.udp.start() + self.ivy.start() - # starting the bus - logging.getLogger('Ivy').setLevel(logging.WARN) - IvyStart(pprz_env.IVY_BUS) - self.ivy_id = IvyBindMsg(self.OnSettingMsg, "(^.* SETTING .*)") + self.run_event.set() - def calculate_checksum(self, msg): - ck_a = 0 - ck_b = 0 - # start char not included in checksum for pprz protocol - for c in msg[1:]: - ck_a = (ck_a + ord(c)) % 256 - ck_b = (ck_b + ck_a) % 256 - return (ck_a, ck_b) + self.status_timer.start() + self.ping_timer.start() - def buildPprzMsg(self, msg_id, *args): - stx = STX - length = 6 - sender = 0 - msg_fields = messages_xml_map.message_dictionary_types["datalink"][msg_id] - struct_string = "=BBBB" - typed_args = [] - idx = 0 - for msg_type in msg_fields: - struct_string += self.data_types[msg_type][0] - length += self.data_types[msg_type][1] - if (msg_type == "float"): - typed_args.append(float(args[idx])) - else: - typed_args.append(int(args[idx])) - idx += 1 - msg = struct.pack(struct_string, stx, length, sender, msg_id, *typed_args) - (ck_a, ck_b) = self.calculate_checksum(msg) - msg = msg + struct.pack('=BB', ck_a, ck_b) - return msg + self.initial_ivy_binds() - def OnSettingMsg(self, agent, *larg): - list = larg[0].split(' ') - sender = list[0] - msg_name = list[1] - ac_id = list[3] - args = list[2:] - msg_id = messages_xml_map.message_dictionary_name_id["datalink"][msg_name] - if self.ac_downlink_status.has_key(int(ac_id)): - msgbuf = self.buildPprzMsg(msg_id, *args) - address = (self.ac_downlink_status[int(ac_id)].address[0], DATALINK_PORT) - self.server.sendto(msgbuf, address) + try: + while True: + time.sleep(.5) + except KeyboardInterrupt: + print ("Stopping UDPLink.") + self.status_timer.cancel() + self.ping_timer.cancel() + self.run_event.clear() + # t.join() + self.udp.stop() + self.ivy.stop() + self.udp.join() def sendPing(self): for (ac_id, value) in self.ac_downlink_status.items(): - msg_id = messages_xml_map.message_dictionary_name_id["datalink"]["PING"] - msgbuf = self.buildPprzMsg(msg_id) - address = (self.ac_downlink_status[int(ac_id)].address[0], DATALINK_PORT) - self.server.sendto(msgbuf, address) - value.last_ping_time = time.clock() - - self.ping_timer = threading.Timer(STATUS_PERIOD, self.sendPing) + if messages_xml_map.PROTOCOL_VERSION=="2.0": + # For pprzlink V2.0 set the receiver id + self.udp.send(message.PprzMessage('datalink','PING'), 0, self.ac_downlink_status[int(ac_id)].address, ac_id) + else: + self.udp.send(message.PprzMessage('datalink','PING'),0,self.ac_downlink_status[int(ac_id)].address) + value.last_ping_time = time.time() + self.ping_timer = threading.Timer(PING_PERIOD, self.sendPing) self.ping_timer.start() def sendStatus(self): for (key, value) in self.ac_downlink_status.items(): - IvySendMsg("%i DOWNLINK_STATUS %i %i %i %i %i %i %i" % ( + self.ivy.send("link LINK_REPORT %i %i %i %i %i %i %i %i %i %i %i" % ( value.ac_id, + -1, value.run_time, + time.time() - value.last_msg_time, value.rx_bytes, value.rx_msgs, self.rx_err, value.rx_bytes - value.last_rx_bytes, value.rx_msgs - value.last_rx_msgs, + value.tx_msgs, 1000 * value.last_pong_time)) value.last_rx_bytes = value.rx_bytes value.last_rx_msgs = value.rx_msgs @@ -158,104 +150,16 @@ def sendStatus(self): self.status_timer = threading.Timer(STATUS_PERIOD, self.sendStatus) self.status_timer.start() - def updateStatus(self, ac_id, length, address, isPong): - if not self.ac_downlink_status.has_key(ac_id): - self.ac_downlink_status[ac_id] = DownLinkStatus(ac_id, address) - - self.ac_downlink_status[ac_id].rx_msgs += 1 - self.ac_downlink_status[ac_id].rx_bytes += length - if isPong: - self.ac_downlink_status[ac_id].last_pong_time = time.clock() - self.ac_downlink_status[ac_id].last_ping_time - - def ProcessPacket(self, msg, address): - if len(msg) < 4: - self.rx_err = self.rx_err + 1 - return - - msg_offset = 0 - while msg_offset < len(msg): - start_byte = ord(msg[msg_offset]) - msg_start_idx = msg_offset - msg_offset = msg_offset + 1 - - if start_byte != STX and start_byte != STX_TS: - self.rx_err = self.rx_err + 1 - return - - msg_length = ord(msg[msg_offset]) - msg_offset = msg_offset + 1 - - if (start_byte == STX_TS): - timestamp = int(self.Unpack(msg, 'L', msg_offset, 4)) - msg_offset = msg_offset + 4 - - ac_id = ord(msg[msg_offset]) - msg_offset = msg_offset + 1 - - msg_id = ord(msg[msg_offset]) - msg_offset = msg_offset + 1 - - msg_name = messages_xml_map.message_dictionary_id_name["telemetry"][msg_id] - msg_fields = messages_xml_map.message_dictionary_types["telemetry"][msg_id] - - ivy_msg = "%i %s " % (ac_id, msg_name) - - for field in msg_fields: - if field[-2:] == "[]": - baseType = field[:-2] - array_length = int(self.Unpack(msg, 'B', msg_offset, 1)) - msg_offset = msg_offset + 1 - for count in range(0, array_length): - array_value = str( - self.Unpack(msg, self.data_types[baseType][0], msg_offset, self.data_types[baseType][1])) - msg_offset = msg_offset + self.data_types[baseType][1] - if (count == array_length - 1): - ivy_msg += array_value + " " - else: - ivy_msg += array_value + "," - else: - ivy_msg += str( - self.Unpack(msg, self.data_types[field][0], msg_offset, self.data_types[field][1])) + " " - msg_offset = msg_offset + self.data_types[field][1] - - if (msg_offset > len(msg)): - print "finished without parsing %s" % field - break - - (ck_a, ck_b) = self.calculate_checksum(msg[msg_start_idx:msg_offset]) - msg_ck_a = int(self.Unpack(msg, 'B', msg_offset, 1)) - msg_offset += 1 - msg_ck_b = int(self.Unpack(msg, 'B', msg_offset, 1)) - msg_offset += 1 - - # check for valid checksum - if (ck_a, ck_b) == (msg_ck_a, msg_ck_b): - self.updateStatus(ac_id, msg_length, address, - msg_id == messages_xml_map.message_dictionary_name_id["telemetry"]["PONG"]) - - # strip off trailing whitespace - ivy_msg = ivy_msg[:-1] - IvySendMsg(ivy_msg) - - def Run(self): - self.server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self.server.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - self.server.bind(('0.0.0.0', DOWNLINK_PORT)) - self.status_timer.start() - self.ping_timer.start() - try: - while True: - (msg, address) = self.server.recvfrom(2048) - self.ProcessPacket(msg, address) - except KeyboardInterrupt: - print("Stopping server on request") - - -def main(): - udp_interface = IvyUdpLink() - udp_interface.Run() - udp_interface.stop() - - if __name__ == '__main__': - main() + from argparse import ArgumentParser + + parser = ArgumentParser(description="UDP link for paparazzi (python version)") + parser.add_argument("--broadcast_method", choices=[IP_BCAST,REPEAT] , default=IP_BCAST, help="Broadcast method - repeating to all known aircraft or sending to IP broadcast address. [default: %(default)s]") + parser.add_argument("--broadcast_address", default=DEFAULT_BROADCAST, help="IP address used for broadcast when broadcast method is IP_BCAST. [default: %(default)s]") + parser.add_argument("--uplink_port", default=pprzlink.udp.UPLINK_PORT, help="Uplink UDP port. [default: %(default)s]") + parser.add_argument("--downlink_port", default=pprzlink.udp.DOWNLINK_PORT, help="Downlink UDP port. [default: %(default)s]") + parser.add_argument("--bus", default=pprzlink.ivy.IVY_BUS, help="Ivy bus. [default to system IVY bus]") + args = parser.parse_args() + + link = UDPLink(args) + link.run() diff --git a/sw/simulator/nps/nps_main_hitl.c b/sw/simulator/nps/nps_main_hitl.c index cb000810558..a5041408db5 100644 --- a/sw/simulator/nps/nps_main_hitl.c +++ b/sw/simulator/nps/nps_main_hitl.c @@ -37,9 +37,6 @@ #include "pprzlink/pprz_transport.h" #include "generated/airframe.h" -/* Message id helpers */ -#define SenderIdOfPprzMsg(x) (x[0]) -#define IdOfPprzMsg(x) (x[1]) #include "nps_main.h" #include "nps_sensors.h"