bosdyn-client 4.0.0__py3-none-any.whl → 4.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,13 +8,12 @@ import logging
8
8
  import time
9
9
  from typing import List
10
10
 
11
+ import bosdyn.client
11
12
  from bosdyn.api import service_fault_pb2
12
13
  from bosdyn.api.graph_nav import area_callback_pb2
13
14
  from bosdyn.api.service_customization_pb2 import DictParam
14
15
  from bosdyn.client.directory import NonexistentServiceError
15
- from bosdyn.client.exceptions import RpcError
16
- from bosdyn.client.fault import (FaultResponseError, ServiceFaultAlreadyExistsError,
17
- ServiceFaultDoesNotExistError)
16
+ from bosdyn.client.fault import ServiceFaultAlreadyExistsError, ServiceFaultDoesNotExistError
18
17
  from bosdyn.client.service_customization_helpers import dict_params_to_dict
19
18
 
20
19
  _LOGGER = logging.getLogger(__name__)
@@ -55,7 +54,7 @@ class AreaCallbackServiceConfig:
55
54
  def handle_service_faults(fault_client, robot_state_client, directory_client, service_name,
56
55
  prereq_services):
57
56
  service_fault = service_fault_pb2.ServiceFault()
58
- service_fault.fault_id.fault_name = f'{service_name}'
57
+ service_fault.fault_id.fault_name = service_name
59
58
  service_fault.fault_id.service_name = service_name
60
59
  service_fault.severity = service_fault_pb2.ServiceFault.SEVERITY_CRITICAL
61
60
  check_period = 0.5 # seconds.
@@ -68,43 +67,68 @@ def handle_service_faults(fault_client, robot_state_client, directory_client, se
68
67
  registered_service = directory_client.get_entry(service_name)
69
68
  except NonexistentServiceError as exc:
70
69
  continue
70
+ except bosdyn.client.Error as exc:
71
+ _LOGGER.error("Failed to check if %s exists during fault handling: %s", service_name,
72
+ exc)
73
+ continue
71
74
 
72
75
  set_fault = False
76
+ fault_exists = False
73
77
  unavailable_services = []
74
- for service in prereq_services:
78
+
79
+ # Need robot state to check existing faults.
80
+ try:
81
+ state = robot_state_client.get_robot_state()
82
+ except bosdyn.client.Error as exc:
83
+ _LOGGER.error("Failed to get robot state during fault handling: %s", exc)
84
+ continue
85
+
86
+ for prereq_service in prereq_services:
75
87
  # Make sure the prereq service exists.
76
88
  try:
77
- registered_service = directory_client.get_entry(service)
89
+ registered_service = directory_client.get_entry(prereq_service)
78
90
  except NonexistentServiceError as exc:
79
91
  set_fault = True
80
- unavailable_services.append(service)
92
+ unavailable_services.append(prereq_service)
93
+ continue
94
+ except bosdyn.client.Error as exc:
95
+ _LOGGER.error("Failed to check if %s exists during fault handling: %s",
96
+ prereq_service, exc)
97
+ set_fault = True
98
+ unavailable_services.append(prereq_service)
81
99
  continue
82
100
 
83
101
  # Make sure the prereq service isn't faulted.
84
- state = robot_state_client.get_robot_state()
85
102
  for fault in state.service_fault_state.faults:
86
- if fault.fault_id.service_name == service:
103
+ if fault.fault_id.service_name == prereq_service:
87
104
  set_fault = True
88
- unavailable_services.append(service)
105
+ unavailable_services.append(prereq_service)
89
106
  break
90
107
 
91
- # Fault the service.
92
- if set_fault:
108
+ # Check if the service is already faulted.
109
+ for fault in state.service_fault_state.faults:
110
+ if fault.fault_id.service_name == service_name:
111
+ fault_exists = True
112
+ break
113
+
114
+ # Fault the service if there isn't an existing fault.
115
+ if set_fault and not fault_exists:
93
116
  service_fault.error_message = 'Faulted due to issues with ' + ','.join(
94
117
  unavailable_services)
95
118
  try:
96
119
  fault_client.trigger_service_fault(service_fault)
120
+ _LOGGER.info("Triggered fault on %s", service_name)
97
121
  except ServiceFaultAlreadyExistsError:
98
122
  pass
99
- except (RpcError, FaultResponseError) as exc:
100
- _LOGGER.error(f"Failed to set {service_name} fault. {exc}")
123
+ except bosdyn.client.Error as exc:
124
+ _LOGGER.error("Failed to set %s fault: %s", service_name, exc)
101
125
 
102
126
  # Otherwise, clear the fault if it exists.
103
- else:
127
+ elif not set_fault and fault_exists:
104
128
  try:
105
129
  fault_client.clear_service_fault(service_fault.fault_id)
106
- set_fault = False
130
+ _LOGGER.info("Cleared fault on %s", service_name)
107
131
  except ServiceFaultDoesNotExistError:
108
132
  pass
109
- except (RpcError, FaultResponseError) as exc:
110
- _LOGGER.error(f"Failed to clear {service_name} fault. {exc}")
133
+ except bosdyn.client.Error as exc:
134
+ _LOGGER.error("Failed to clear %s fault: %s", service_name, exc)
@@ -149,6 +149,11 @@ class NMEAParser(object):
149
149
  self.last_failed_read_log_time = now
150
150
  continue
151
151
 
152
+ # if the message does not contain a timestamp attribute, abandon the rest of the logic
153
+ # and go to the beginning of the loop
154
+ if not hasattr(nmea_msg, 'timestamp'):
155
+ continue
156
+
152
157
  # Only use NMEA messages that have a timestamp.
153
158
  # For example, GSA and GST messages are not supported.
154
159
  if isinstance(nmea_msg.timestamp, datetime.time):
@@ -27,17 +27,21 @@ class NMEAStreamReader(object):
27
27
  # The amount of time to wait before logging another decode error.
28
28
  LOG_THROTTLE_TIME = 2.0 # seconds.
29
29
 
30
- def __init__(self, logger, stream, body_tform_gps):
30
+ def __init__(self, logger, stream, body_tform_gps, verbose):
31
31
  self.logger = logger
32
32
  self.stream = stream
33
33
  self.parser = NMEAParser(logger)
34
34
  self.body_tform_gps = body_tform_gps.to_proto()
35
35
  self.last_failed_read_log_time = None
36
+ self.verbose = verbose
36
37
 
37
38
  def read_data(self, time_converter: RobotTimeConverter) -> List[GpsDataPoint]:
38
39
  """This function returns an array of new GpsDataPoints."""
39
40
  try:
40
41
  raw_data = self.stream.readline()
42
+ # If the rawdata is a bytes or bytearray object, decode it into a string.
43
+ if type(raw_data) is not str:
44
+ raw_data = str(raw_data, "utf-8")
41
45
  except UnicodeDecodeError:
42
46
  # Throttle the logs.
43
47
  now = time.time()
@@ -53,7 +57,12 @@ class NMEAStreamReader(object):
53
57
 
54
58
  # Trim any leading characters before the NMEA sentence.
55
59
  raw_data = raw_data[raw_data.index('$'):]
56
- self.logger.info(f"Read: {raw_data}")
60
+
61
+ # If we are being verbose, print the message we received.
62
+ if self.verbose:
63
+ self.logger.info(f"Read: {raw_data}")
64
+
65
+ # Parse the received message.
57
66
  new_points = self.parser.parse(raw_data, time_converter, check=False)
58
67
 
59
68
  # Offset for the GPS
@@ -65,11 +74,11 @@ class NMEAStreamReader(object):
65
74
 
66
75
  class GpsListener:
67
76
 
68
- def __init__(self, robot, time_converter, stream, name, body_tform_gps, logger):
77
+ def __init__(self, robot, time_converter, stream, name, body_tform_gps, logger, verbose):
69
78
  self.logger = logger
70
79
  self.robot = robot
71
80
  self.time_converter = time_converter
72
- self.reader = NMEAStreamReader(logger, stream, body_tform_gps)
81
+ self.reader = NMEAStreamReader(logger, stream, body_tform_gps, verbose)
73
82
  self.gps_device = GpsDevice()
74
83
  self.gps_device.name = name
75
84
  self.aggregator_client = None
@@ -9,6 +9,7 @@
9
9
  import copy
10
10
  import logging
11
11
  import signal
12
+ import sys
12
13
  import time
13
14
  from concurrent import futures
14
15
 
@@ -133,7 +134,9 @@ class GrpcServiceRunner(object):
133
134
  signal.signal(signal.SIGINT, signal.default_int_handler)
134
135
  # Included SIGTERM for "docker stop". See https://docs.docker.com/engine/reference/commandline/stop/
135
136
  signal.signal(signal.SIGTERM, signal.default_int_handler)
136
- signal.signal(signal.SIGQUIT, signal.default_int_handler)
137
+ # OS check because on Windows, signal() can only be called with SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, or SIGTERM.
138
+ if not sys.platform.startswith("win32"):
139
+ signal.signal(signal.SIGQUIT, signal.default_int_handler)
137
140
 
138
141
  # Monitor for SIGINT, SIGTERM, or SIGQUIT and shut down cleanly.
139
142
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bosdyn-client
3
- Version: 4.0.0
3
+ Version: 4.0.2
4
4
  Summary: Boston Dynamics API client code and interfaces
5
5
  Home-page: https://dev.bostondynamics.com/
6
6
  Author: Boston Dynamics
@@ -15,8 +15,8 @@ Classifier: Programming Language :: Python :: 3.10
15
15
  Classifier: License :: Other/Proprietary License
16
16
  Classifier: Operating System :: OS Independent
17
17
  Description-Content-Type: text/markdown
18
- Requires-Dist: bosdyn-api (==4.0.0)
19
- Requires-Dist: bosdyn-core (==4.0.0)
18
+ Requires-Dist: bosdyn-api (==4.0.2)
19
+ Requires-Dist: bosdyn-core (==4.0.2)
20
20
  Requires-Dist: grpcio
21
21
  Requires-Dist: pyjwt
22
22
  Requires-Dist: numpy
@@ -5,7 +5,7 @@ bosdyn/client/area_callback.py,sha256=nQnhJR8-f0PMq9uILpKhYitVuIZHl6VViUDndN2K4u
5
5
  bosdyn/client/area_callback_region_handler_base.py,sha256=cr5SwGogXmuMbAbbMeHvQZQBflYyFTOCj7wrUOgsUHQ,16467
6
6
  bosdyn/client/area_callback_service_runner.py,sha256=Rr30BV3TSXHQGcsUGlTa1F-noQDvgq6wv5XxQ_zTIa0,1869
7
7
  bosdyn/client/area_callback_service_servicer.py,sha256=o1kYKV83Q-ud-_rmT17XTSqBdHqph_xYsgvvnpjsKtE,13229
8
- bosdyn/client/area_callback_service_utils.py,sha256=rkHfV5PLrkUUVO0ZvUCxFlCvgyJ8-jixfwL34_iLTPM,4770
8
+ bosdyn/client/area_callback_service_utils.py,sha256=R8ljJe8fPszMI6RyuGRyv_QGu63kw1yZAveZydlpERI,5858
9
9
  bosdyn/client/arm_surface_contact.py,sha256=DRfPfsFEzfk6ufe080ViqasUefl2ZUtcvcNENgcf55k,3710
10
10
  bosdyn/client/async_tasks.py,sha256=gEPev6_jaUCe-G5PqktMiMGb7ohDy0daunxzQD5jafg,5594
11
11
  bosdyn/client/auth.py,sha256=YLo6jP0Ssl_Z6rHtTiPiKUNIweDRYub9w3iHdUe6n40,5302
@@ -62,7 +62,7 @@ bosdyn/client/robot_command.py,sha256=D6MQ8Shx8gV4IZMfzaaTgmT04FiamUkC9eN41VORrL
62
62
  bosdyn/client/robot_id.py,sha256=0VZHG9hltwTLAm1_Bt26Xq1O6EROswqNwHvjY7kaplk,2482
63
63
  bosdyn/client/robot_state.py,sha256=h551ke5eHdAC7NgVuLphY8FZR899Ii8_lYwuoX1w1nk,7073
64
64
  bosdyn/client/sdk.py,sha256=u-DOSF-QEERYu0hxRXmfOpRhLCD6R-b5IqgfsqUaOcY,12759
65
- bosdyn/client/server_util.py,sha256=CjjB0v1EPua7votsgHOLWKwSNz8IYd1V0u7DfjKACPk,10204
65
+ bosdyn/client/server_util.py,sha256=nzpZijK_GclVK2Zf2g2KCe-2e49NEQbPgdz75fwafXc,10402
66
66
  bosdyn/client/service_customization_helpers.py,sha256=mi_xkCNvJE7wX64WFoMAKiJQsUvS33LY8PrhiV8-95w,48357
67
67
  bosdyn/client/signals_helpers.py,sha256=Sp91IrMxVU-PeH6TK2njzFCKmFMyshRJqNa4DYRMqDU,3682
68
68
  bosdyn/client/spot_check.py,sha256=Jvlli3xTOzlrHE6OadLJ662zoUM87jUyQewGFOYM85o,21119
@@ -72,10 +72,10 @@ bosdyn/client/token_manager.py,sha256=FvDFCXKIiGXZNkagKZM41Ut8Q0ChlYHN3O61CzrqMF
72
72
  bosdyn/client/units_helpers.py,sha256=5SAmL8vsnl06oGNjzb57fUkuUbGvtbeNdg4NgW0wYAY,1084
73
73
  bosdyn/client/util.py,sha256=1Kj10p0jqS7opwDrAAx3adfIw1lJCB1OzSZYyfUlJH8,20029
74
74
  bosdyn/client/world_object.py,sha256=KbFRkG3jqQEfRN6SmSv1_D6n_9yFVYwbfCUWQ7kYpio,18695
75
- bosdyn/client/gps/NMEAParser.py,sha256=EMyEt7KJ3QvQpTqq8gwZ9ZIKV7RRGvjJnQyY067i9Q4,8048
75
+ bosdyn/client/gps/NMEAParser.py,sha256=1SSaxN1D7V5eUnqnuCpO6gFwWofurtvXg7UbxF4d3ec,8274
76
76
  bosdyn/client/gps/__init__.py,sha256=1qUAbnMKYlERYZvxtGz4ThjYef7Tx-ZBclLoVE_ecjU,265
77
77
  bosdyn/client/gps/aggregator_client.py,sha256=z5iRAYyCIez7p0EzIqZg3NTJGzxXAy297iENrhaL7CQ,2380
78
- bosdyn/client/gps/gps_listener.py,sha256=r08r1qCaLVoE1mcMOMyXWHywfKdTTNeFf7SOGpJBkl0,6181
78
+ bosdyn/client/gps/gps_listener.py,sha256=KkQsThiBgUwmsys34jGn0BrHuE6RkfcwSN7nDwfNpTA,6552
79
79
  bosdyn/client/gps/registration_client.py,sha256=LqDLl_Ezv3HNUr9R1B4n2hcMArmGwLgg1asCkGhe2WA,1901
80
80
  bosdyn/client/resources/__init__.py,sha256=1qUAbnMKYlERYZvxtGz4ThjYef7Tx-ZBclLoVE_ecjU,265
81
81
  bosdyn/client/resources/robot.pem,sha256=kWAr4xK29RtTVC_EhbwW2_NblIuecYqVudR2YIdTh84,1874
@@ -91,7 +91,7 @@ bosdyn/client/spot_cam/power.py,sha256=HS3nJF8hXq9m1JziOIwLHGLtlNMyLgewWBgs-mRZm
91
91
  bosdyn/client/spot_cam/ptz.py,sha256=8e6fA07aGnymSXV2MB_QBx0Pv4PSAMOihxq1jyoinDU,10815
92
92
  bosdyn/client/spot_cam/streamquality.py,sha256=hQzVPdKnzVT91fc8E8AmNqhAPgddt0XE2tzNQD6QefQ,6411
93
93
  bosdyn/client/spot_cam/version.py,sha256=R82eyCAY9PfZqbN8D6hNzSeZatpgpsFr995dRt1Mbe0,2856
94
- bosdyn_client-4.0.0.dist-info/METADATA,sha256=JiZoKvStlWEjgFO4DGdG_U0Wis0fknhnV4FcuLuyYSM,3938
95
- bosdyn_client-4.0.0.dist-info/WHEEL,sha256=AtBG6SXL3KF_v0NxLf0ehyVOh0cold-JbJYXNGorC6Q,92
96
- bosdyn_client-4.0.0.dist-info/top_level.txt,sha256=an2OWgx1ej2jFjmBjPWNQ68ZglvUfKhmXWW-WhTtDmA,7
97
- bosdyn_client-4.0.0.dist-info/RECORD,,
94
+ bosdyn_client-4.0.2.dist-info/METADATA,sha256=4_AUjtA0swqP4G9fZ_8UHTgq9iZFCPy_wkPdskwDn2w,3938
95
+ bosdyn_client-4.0.2.dist-info/WHEEL,sha256=AtBG6SXL3KF_v0NxLf0ehyVOh0cold-JbJYXNGorC6Q,92
96
+ bosdyn_client-4.0.2.dist-info/top_level.txt,sha256=an2OWgx1ej2jFjmBjPWNQ68ZglvUfKhmXWW-WhTtDmA,7
97
+ bosdyn_client-4.0.2.dist-info/RECORD,,