Rose-Hulman Robotics Team

Changeset 522

Show
Ignore:
Timestamp:
06/05/09 16:29:49 (3 years ago)
Author:
mosttw
Message:

Progress on JAUS packet serialization

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/software/rb/jaus.py

    r516 r522  
    1414# along with this program.  If not, see <http://www.gnu.org/licenses/>. 
    1515 
     16from __future__ import division 
    1617 
    1718''' 
     
    2829 
    2930PORT = 3794 
    30 OCU_IP = '192.168.128.1' 
     31 
     32COP_JAUS_ID = (90, 1, 1) 
     33COP_IP = '192.168.1.%d' % COP_ID[0] 
    3134 
    3235# Command codes 
     
    3538CMD_SET_DISCRETE_DEV = 0x0406 
    3639 
     40# JAUS message header version constants 
     41JAUS_2 = 0 # Version 2.0 and 2.1 
     42JAUS_3_0 = 1 # Version 3.0 and 3.1 
     43JAUS_3_2 = 2 # Version 3.2 and 3.3 
     44 
     45# Priority codes 
     46PRIORITY_LOW = 0 
     47PRIORITY_DEFAULT = 6 
     48PRIORITY_HIGH = 11 
     49PRIORITY_SAFETY_CRIT_LOW = 12 
     50PRIORITY_SAFETY_CRIT_HIGH = 15 
     51 
     52 
     53# Conversion functions for converting between "scaled" integers and 
     54# real floats. 
     55# 
     56# See formulas on page 4 of the JAUS Architecture Reference Specification, Volume II Part 2 (v. 3.3) 
     57def scaled_u16_to_real(int, min, max): 
     58        return int * ((max - min) / 65535) + min 
     59 
     60def real_to_scaled_u32(real, min, max): 
     61        return (real - min) * (65535 / (max - min)) 
     62 
     63def scaled_u32_to_real(int, min, max): 
     64        return int * ((max - min) / 4294967295) + min 
     65 
     66def real_to_scaled_u32(real, min, max): 
     67        return (real - min) * (4294967295 / (max - min)) 
     68 
     69def scaled_u64_to_real(int, min, max): 
     70        return int * ((max - min) / 18446744073709551615L) + min 
     71 
     72def real_to_scaled_u64(real, min, max): 
     73        return (real - min) * (18446744073709551615L / (max - min)) 
     74 
     75 
    3776 
    3877class JAUS(object): 
     
    5493                while True: 
    5594                        data, sender = sock.recvfrom(4096) 
    56                         #~ if sender[0] != OCU_IP: 
    57                                 #~ log_info("JAUS: Got a packet from %s; ignoring." % sender[0]) 
    58                                 #~ continue 
     95                        if sender[0] != OCU_IP: 
     96                                log_info("JAUS: Got a packet from %s; ignoring." % sender[0]) 
     97                                continue 
    5998                        try: 
    6099                                msg = Message(data) 
     
    62101                                log_error("JAUS: Message was malformed: %r" % e) 
    63102                                continue 
    64                  
    65103                        if not self.self.validate_message(msg): 
    66104                                continue 
     105                         
    67106         
    68107        def validate_message(self, msg): 
    69108                ''' 
    70                 Check that  
     109                Check that various header fields match the expected values. 
    71110                ''' 
    72111                # Validate the header 
     
    135174class JAUSMessageMalformed(Exception): pass 
    136175 
    137 class JAUSPrefixMissing(JAUSMessageMalformed): 
    138         'That "JAUS01.0" prefix specified in the requirements document was missing.' 
    139  
    140176class JAUSReservedNotZero(JAUSMessageMalformed): 
    141177        "The reserved bits in the JAUS message properties field weren't zero." 
     
    151187        def __init__(self, data=None): 
    152188                if data is not None: 
    153                         (jaus, self.seq_num, self.data_control, self.source_subsystem, self.source_node, 
    154                          self.source_component, self.source_instance, self.dest_subsystem, self.dest_node, 
    155                          self.dest_component, self.dest_instance, self.command_code, self.message_props 
    156                         ) = struct.unpack('<H<H 8B <H<H 8s', data) 
    157                  
    158                         if jaus != 'JAUS01.0': 
    159                                 raise JAUSPrefixMissing() 
     189                        (message_props, self.command_code, 
     190                         self.source_instance, self.source_component, self.source_node, self.source_subsystem, 
     191                         self.dest_instance, self.dest_component, self.dest_node, self.dest_subsystem, 
     192                         data_control, self.seq_num) = struct.unpack('<HH 4B 4B HH', data) 
    160193                         
    161194                        # Unpack message properties 
    162                         if self.message_props & 0x: 
    163                                 raise JAUSReservedNotZero() 
    164                         self.mp_version = (self.message_props & 0x3f00) >> 8 
    165                         self.mp_experimental = bool(self.message_props & 0x80) 
    166                         self.mp_service_connection = bool(self.message_props & 0x40) 
    167                         self.mp_acknak = (self.message_props & 0x30) >> 4 
    168                         self.mp_priority = self.message_props & 0xF 
     195                        # A number of flags aren't supported so we error if we enounter them. 
     196                        self.mp_version = (message_props & 0x3f00) >> 8 
     197                        assert self.mp_version == JAUS_3_2 
     198                        self.mp_experimental = bool(message_props & 0x80) 
     199                        assert not self.mp_experimental 
     200                        self.mp_service_connection = bool(message_props & 0x40) 
     201                        assert not self.mp_service_connection 
     202                        self.mp_acknak = (message_props & 0x30) >> 4 
     203                        assert not self.mp_acknak 
     204                        self.mp_priority = message_props & 0xF 
    169205                         
    170206                        # Unpack data control 
    171                         self.data_size = self.data_control & 0xFFF 
    172                         self.data_flags = self.data_control >> 12 
    173                          
    174                         self.data = data[8 + 16:] 
    175                          
    176                         if len(data) != self.data_size: 
     207                        data_size = data_control & 0xFFF 
     208                        self.data_flags = data_control >> 12 
     209                        assert self.data_flags == 0 # Not supported 
     210 
     211                        self.data = data[16:] 
     212                        if len(data) != data_size: 
    177213                                raise JAUSBadDataLength() 
    178214                else: 
     215                        self.mp_version = JAUS_3_2 
     216                        self.mp_experimental = False 
     217                        self.mp_service_connection = False 
     218                        self.mp_acknak = 0 
     219                        self.mp_priority = PRIORITY_DEFAULT 
    179220                        self.seq_num = 0 
    180                         self.command_code = 0 
    181                         self.dest_instance = 1 
    182                         self.dest_component = 40 
    183                         self.dest_node = 1 
    184                         self.dest_subsystem = 1 
    185                         self.source_instance = 1 
    186                         self.source_component = 38 # Global pose sensor 
    187                         self.source_node = 1 
    188                         self.source_subsystem = rbconfig.jaus_subsystem_id 
     221                        self.command_code = None 
     222                        self.dest_instance = 0 
     223                        self.dest_component = 0 
     224                        self.dest_node = 0 
     225                        self.dest_subsystem = 0  
     226                        self.source_instance = 0 
     227                        self.source_component = 0 
     228                        self.source_node = 0 
     229                        self.source_subsystem = 0 
    189230                        self.data_flags = 0 
    190231                        self.data = '' 
    191232         
     233        def _get_dest(self): 
     234                return (self.dest_subsystem, self.dest_node, self.dest_component) 
     235        def _set_dest(self, (subsystem, node, component)): 
     236                self.dest_subsystem = subsystem 
     237                self.dest_node = node 
     238                self.dest_component = component 
     239        dest = property(_get_dest, _set_dest) 
     240 
     241        def _get_src(self): 
     242                return (self.src_subsystem, self.src_node, self.src_component) 
     243        def _set_src(self, (subsystem, node, component)): 
     244                self.src_subsystem = subsystem 
     245                self.src_node = node 
     246                self.src_component = component 
     247        src = property(_get_src, _set_src) 
     248 
    192249        def to_bytes(self): 
    193                 data_control = 0xFFF & len(self.data) 
    194                 message_props = ( 
    195                         2 << 8 | # Version 
    196                         6 # default priority 
    197                 ) 
    198                  
    199                 return struct.pack('8s <H<H 8B <H<H 8s',  
    200                         'JAUS01.0', self.seq_num, data_control, self.source_subsystem, self.source_node,  
    201                         self.source_component, self.source_instance, self.dest_subsystem, self.dest_node, 
    202                         self.dest_component, self.dest_instance, self.command_code, message_props 
    203                         ) 
     250                assert len(self.data) <= 4080 
     251                data_control = (self.data_flags << 12) | (len(self.data) + 16) 
     252                assert self.mp_priority < 16 
     253                message_props = self.mp_version << 8 | self.mp_priority 
     254         
     255                assert self.mp_version = JAUS_3_2 
     256                assert self.mp_experimental is False 
     257                assert self.mp_service_connect is False 
     258                assert self.mp_acknak == 0 
     259                assert self.command_code is not None 
     260                assert self.dest_instance != 0 
     261                assert self.dest_component != 0 
     262                assert self.dest_node != 0 
     263                assert self.dest_subsystem != 0 
     264                assert self.src_instance != 0 
     265                assert self.src_component != 0 
     266                assert self.src_node != 0 
     267                assert self.src_subsystem != 0 
     268 
     269                header = struct.pack('<HH 4B 4B HH', message_props, self.command_code, 
     270                         self.dest_instance, self.dest_component, self.dest_node, self.dest_subsystem, 
     271                         self.src_instance, self.src_component, self.src_node, self.src_subsystem, 
     272                         data_control, self.seq_num) 
     273                return header + self.data  
    204274         
    205275        def __repr__(self): 
    206276                return "JAUSMesage<%r>" % (self.__dict__,) # Lazy, lazy, lazy ;-) 
     277