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.
- bosdyn/client/area_callback_service_utils.py +42 -18
- bosdyn/client/gps/NMEAParser.py +5 -0
- bosdyn/client/gps/gps_listener.py +13 -4
- bosdyn/client/server_util.py +4 -1
- {bosdyn_client-4.0.0.dist-info → bosdyn_client-4.0.2.dist-info}/METADATA +3 -3
- {bosdyn_client-4.0.0.dist-info → bosdyn_client-4.0.2.dist-info}/RECORD +8 -8
- {bosdyn_client-4.0.0.dist-info → bosdyn_client-4.0.2.dist-info}/WHEEL +0 -0
- {bosdyn_client-4.0.0.dist-info → bosdyn_client-4.0.2.dist-info}/top_level.txt +0 -0
|
@@ -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.
|
|
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 =
|
|
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
|
-
|
|
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(
|
|
89
|
+
registered_service = directory_client.get_entry(prereq_service)
|
|
78
90
|
except NonexistentServiceError as exc:
|
|
79
91
|
set_fault = True
|
|
80
|
-
unavailable_services.append(
|
|
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 ==
|
|
103
|
+
if fault.fault_id.service_name == prereq_service:
|
|
87
104
|
set_fault = True
|
|
88
|
-
unavailable_services.append(
|
|
105
|
+
unavailable_services.append(prereq_service)
|
|
89
106
|
break
|
|
90
107
|
|
|
91
|
-
#
|
|
92
|
-
|
|
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
|
|
100
|
-
_LOGGER.error(
|
|
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
|
-
|
|
127
|
+
elif not set_fault and fault_exists:
|
|
104
128
|
try:
|
|
105
129
|
fault_client.clear_service_fault(service_fault.fault_id)
|
|
106
|
-
|
|
130
|
+
_LOGGER.info("Cleared fault on %s", service_name)
|
|
107
131
|
except ServiceFaultDoesNotExistError:
|
|
108
132
|
pass
|
|
109
|
-
except
|
|
110
|
-
_LOGGER.error(
|
|
133
|
+
except bosdyn.client.Error as exc:
|
|
134
|
+
_LOGGER.error("Failed to clear %s fault: %s", service_name, exc)
|
bosdyn/client/gps/NMEAParser.py
CHANGED
|
@@ -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
|
-
|
|
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
|
bosdyn/client/server_util.py
CHANGED
|
@@ -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
|
|
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.
|
|
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.
|
|
19
|
-
Requires-Dist: bosdyn-core (==4.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=
|
|
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=
|
|
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=
|
|
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=
|
|
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.
|
|
95
|
-
bosdyn_client-4.0.
|
|
96
|
-
bosdyn_client-4.0.
|
|
97
|
-
bosdyn_client-4.0.
|
|
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,,
|
|
File without changes
|
|
File without changes
|