| | 40 | # JAUS message header version constants |
| | 41 | JAUS_2 = 0 # Version 2.0 and 2.1 |
| | 42 | JAUS_3_0 = 1 # Version 3.0 and 3.1 |
| | 43 | JAUS_3_2 = 2 # Version 3.2 and 3.3 |
| | 44 | |
| | 45 | # Priority codes |
| | 46 | PRIORITY_LOW = 0 |
| | 47 | PRIORITY_DEFAULT = 6 |
| | 48 | PRIORITY_HIGH = 11 |
| | 49 | PRIORITY_SAFETY_CRIT_LOW = 12 |
| | 50 | PRIORITY_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) |
| | 57 | def scaled_u16_to_real(int, min, max): |
| | 58 | return int * ((max - min) / 65535) + min |
| | 59 | |
| | 60 | def real_to_scaled_u32(real, min, max): |
| | 61 | return (real - min) * (65535 / (max - min)) |
| | 62 | |
| | 63 | def scaled_u32_to_real(int, min, max): |
| | 64 | return int * ((max - min) / 4294967295) + min |
| | 65 | |
| | 66 | def real_to_scaled_u32(real, min, max): |
| | 67 | return (real - min) * (4294967295 / (max - min)) |
| | 68 | |
| | 69 | def scaled_u64_to_real(int, min, max): |
| | 70 | return int * ((max - min) / 18446744073709551615L) + min |
| | 71 | |
| | 72 | def real_to_scaled_u64(real, min, max): |
| | 73 | return (real - min) * (18446744073709551615L / (max - min)) |
| | 74 | |
| | 75 | |
| 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) |
| 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 |
| | 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 | |
| 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 |