standardbots 2.0.1__tar.gz → 2.1.1__tar.gz

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.

Potentially problematic release.


This version of standardbots might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: standardbots
3
- Version: 2.0.1
3
+ Version: 2.1.1
4
4
  Summary: Standard Bots RO1 Robotics API
5
5
  Home-page:
6
6
  Author: Standard Bots Support
@@ -1,9 +1,11 @@
1
- You can test the API by using the playground, add your own file or use the existing python scripts.
2
- When a client has an issue, and they send their code. It's helpful to test their code to see possible issues
1
+ You can test the API by using the playground, add your own file or use the
2
+ existing python scripts. When a client has an issue, and they send their code.
3
+ It's helpful to test their code to see possible issues
3
4
 
4
5
  # ENABLE API ON YOUR LOCAL MACHINE
5
6
 
6
- Follow the steps here https://www.notion.so/standardbots/Using-the-REST-API-b2c778d47969444dac61483f0117acad
7
+ Follow the steps here
8
+ https://www.notion.so/standardbots/Using-the-REST-API-b2c778d47969444dac61483f0117acad
7
9
 
8
10
  # CONFIG
9
11
 
@@ -11,7 +13,8 @@ At the top of the file, use your token
11
13
 
12
14
  # RUN
13
15
 
14
- To run a script move into the `sdks/python` folder and run `python playground/filename.py`
16
+ To run a script move into the `sdks/python` folder and run
17
+ `python playground/filename.py`
15
18
 
16
19
  # To create a test build
17
20
 
@@ -48,8 +51,8 @@ To set up tests:
48
51
  cd sdks/python
49
52
  ```
50
53
 
51
- Note: Make sure to select proper python interpreter.
52
- Sometimes there is an error related to missing "dotenv" module, to solve this install it separately
54
+ Note: Make sure to select proper python interpreter. Sometimes there is an error
55
+ related to missing "dotenv" module, to solve this install it separately
53
56
 
54
57
  ```
55
58
  python3 -m pip install python-dotenv
@@ -60,16 +63,18 @@ python3 -m pip install -r requirements-dev.txt
60
63
 
61
64
  #### Sample routine
62
65
 
63
- You need to add the sample routine in [sdks/python/tests/fixtures/test_public_api_routine.json](./tests/fixtures/test_public_api_routine.json) to your target test environment (i.e. upload the routine to ).
66
+ You need to add the sample routine in
67
+ [sdks/python/tests/fixtures/test_public_api_routine.json](./tests/fixtures/test_public_api_routine.json)
68
+ to your target test environment (i.e. upload the routine to ).
64
69
 
65
70
  The name of routine should be "Test Public API"
66
71
 
67
72
  #### Sample globals
68
73
 
69
- - _Variable._ Add global variable called "test_public_api_global" with any value.
74
+ - _Variable._ Add global variable called "test_public_api_global" with any
75
+ value.
70
76
  - _Space._ Create a global space called "Test global space" of any kind.
71
77
 
72
-
73
78
  ## Running
74
79
 
75
80
  Here is a basic test command:
@@ -81,7 +86,8 @@ SB_API_TOKEN=...
81
86
  python3 -m pytest ./tests --cov=standardbots --token=$SB_API_TOKEN --api-url=$SB_API_URL
82
87
  ```
83
88
 
84
- You may also set up a `.env` file at `sdks/python/.env` with the following contents:
89
+ You may also set up a `.env` file at `sdks/python/.env` with the following
90
+ contents:
85
91
 
86
92
  ```bash
87
93
  export SB_API_URL=http://34.162.0.32:3000
@@ -96,38 +102,43 @@ python3 -m pytest ./tests --cov=standardbots
96
102
 
97
103
  ### Robot state and testing (Markers)
98
104
 
99
- We need the bot to be in a certain state to run certain tests. For example, we need a routine to be running in order to stop the routine. Camera should be connected by default.
105
+ We need the bot to be in a certain state to run certain tests. For example, we
106
+ need a routine to be running in order to stop the routine. Camera should be
107
+ disconnected by default.
100
108
 
101
109
  At start of testing, robot should:
102
110
 
103
111
  - _NOT_ be e-stopped.
104
112
 
105
-
106
113
  The basic idea here is:
107
114
 
108
115
  - These special tests will not be run by default.
109
- - You may pass a flag (e.g. `--camera-disconnected`) when the bot is in the correct state to run the tests.
116
+ - You may pass a flag (e.g. `--camera-connected`) when the bot is in the correct
117
+ state to run the tests.
110
118
  - Markers usage:
111
- - When `--gripper=<type>` flag is passed(`type` is value from `GripperKindEnum` enum):
119
+ - When `--gripper=<type>` flag is passed(`type` is value from `GripperKindEnum`
120
+ enum):
112
121
  1. Tests expect that this specific gripper is connected
113
122
  2. Tests without the flag are not run.
114
- - When `--camera-disconnected` flag is passed:
123
+ - When `--camera-connected` flag is passed:
115
124
  1. Tests with the flag are run.
116
125
  2. Tests without the flag are not run.
117
126
 
118
- We use [pytest markers](https://docs.pytest.org/en/7.1.x/example/markers.html) to do this.
127
+ We use [pytest markers](https://docs.pytest.org/en/7.1.x/example/markers.html)
128
+ to do this.
119
129
 
120
130
  #### Camera disconnected
121
131
 
122
132
  The wrist camera should be disabled. Then run:
123
133
 
124
134
  ```bash
125
- python3 -m pytest ./tests --cov=standardbots --camera-disconnected
135
+ python3 -m pytest ./tests --cov=standardbots --camera-connected
126
136
  ```
127
137
 
128
138
  #### E-stop
129
139
 
130
- No marker needed for e-stop. However, we do rely on active recovery of e-stop and getting the failure state in order to do these tests.
140
+ No marker needed for e-stop. However, we do rely on active recovery of e-stop
141
+ and getting the failure state in order to do these tests.
131
142
 
132
143
  When e-stop test runs, cannot have bot in a failure state (pre-test will fail).
133
144
 
@@ -151,16 +162,19 @@ tests/test_apis.py
151
162
  Fixes:
152
163
 
153
164
  - _Make sure you can log into remote control._ Ensure that botman is connected.
154
- - _Ensure that the robot URL is up-to-date._ Botman url will often change when you reboot.
165
+ - _Ensure that the robot URL is up-to-date._ Botman url will often change when
166
+ you reboot.
155
167
 
156
168
  ### Custom sensors
157
169
 
158
170
  To test custom sensors:
171
+
159
172
  - go to the menu on the left bottom corner;
160
173
  - Click on 'Equipment';
161
174
  - Add Gripper > Custom Gripper;
162
175
  - Go to the Sensors tab and click 'Add Sensor';
163
- - Keep the default values as they are (name: 'Sensor 1', kind: 'Control Box IO', sensor value: 'low');
176
+ - Keep the default values as they are (name: 'Sensor 1', kind: 'Control Box IO',
177
+ sensor value: 'low');
164
178
  - Hit 'Save' and make sure the Custom Gripper is enabled.
165
179
 
166
180
  Then run:
@@ -173,11 +187,13 @@ python3 -m pytest ./tests --cov=standardbots --gripper=custom_sensors
173
187
 
174
188
  > See command: `botctl publicapi test:setup-bot`.
175
189
 
176
- We now have a common robot database state that can be used for testing. While this isn't necessary for use, it does provide a common state for testing.
190
+ We now have a common robot database state that can be used for testing. While
191
+ this isn't necessary for use, it does provide a common state for testing.
177
192
 
178
193
  ### How to create a new backup
179
194
 
180
- In the place where you are running the stack and want to create the backup (e.g. on the control box):
195
+ In the place where you are running the stack and want to create the backup (e.g.
196
+ on the control box):
181
197
 
182
198
  ```bash
183
199
  DB_USER=sb
@@ -13,7 +13,7 @@
13
13
  from setuptools import setup, find_packages # noqa: H301
14
14
 
15
15
  NAME = "standardbots"
16
- VERSION = "2.0.1"
16
+ VERSION = "2.1.1"
17
17
  # To install the library, run the following
18
18
  #
19
19
  # python setup.py install
@@ -2478,6 +2478,8 @@ class RecorderStatus(Enum):
2478
2478
  """Enum Error = `error`"""
2479
2479
  Complete = "complete"
2480
2480
  """Enum Complete = `complete`"""
2481
+ Initializing = "initializing"
2482
+ """Enum Initializing = `initializing`"""
2481
2483
 
2482
2484
  def parse_recorder_status(data: object) -> RecorderStatus:
2483
2485
  return RecorderStatus(data)
@@ -6445,7 +6447,7 @@ class RecorderBotDetails:
6445
6447
  if value is None:
6446
6448
  return [True, ""]
6447
6449
 
6448
- if not ((isinstance(value, str) and RecorderStatus in ['not_recording', 'recording', 'error', 'complete']) or isinstance(value, RecorderStatus)):
6450
+ if not ((isinstance(value, str) and RecorderStatus in ['not_recording', 'recording', 'error', 'complete', 'initializing']) or isinstance(value, RecorderStatus)):
6449
6451
  return [False, "status must be of type RecorderStatus for RecorderBotDetails, got " + type(value).__name__]
6450
6452
 
6451
6453
  return [True, ""]
@@ -8780,7 +8782,7 @@ class RecorderState:
8780
8782
  if value is None:
8781
8783
  return [True, ""]
8782
8784
 
8783
- if not ((isinstance(value, str) and RecorderStatus in ['not_recording', 'recording', 'error', 'complete']) or isinstance(value, RecorderStatus)):
8785
+ if not ((isinstance(value, str) and RecorderStatus in ['not_recording', 'recording', 'error', 'complete', 'initializing']) or isinstance(value, RecorderStatus)):
8784
8786
  return [False, "status must be of type RecorderStatus for RecorderState, got " + type(value).__name__]
8785
8787
 
8786
8788
  return [True, ""]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: standardbots
3
- Version: 2.0.1
3
+ Version: 2.1.1
4
4
  Summary: Standard Bots RO1 Robotics API
5
5
  Home-page:
6
6
  Author: Standard Bots Support
@@ -285,17 +285,17 @@ class TestGetEquipment:
285
285
  assert isinstance(res.data, models.GetEquipmentConfigResponse)
286
286
  assert res.data.equipment is not None
287
287
  assert isinstance(res.data.equipment, list)
288
- assert len(res.data.equipment) > 0
289
- assert isinstance(res.data.equipment[0], models.EquipmentConfig)
288
+ if len(res.data.equipment) > 0:
289
+ assert isinstance(res.data.equipment[0], models.EquipmentConfig)
290
290
 
291
- equipment = res.data.equipment[0]
292
- assert equipment.id is not None
293
- assert equipment.kind is not None
294
- assert equipment.is_enabled is not None
295
- assert equipment.config is not None
291
+ equipment = res.data.equipment[0]
292
+ assert equipment.id is not None
293
+ assert equipment.kind is not None
294
+ assert equipment.is_enabled is not None
295
+ assert equipment.config is not None
296
296
 
297
- # Can be parsed as JSON
298
- assert json.loads(equipment.config) is not None
297
+ # Can be parsed as JSON
298
+ assert json.loads(equipment.config) is not None
299
299
 
300
300
 
301
301
  class TestGetEquipmentEndEffectorConfiguration:
@@ -991,12 +991,12 @@ class TestPostMovementBrakesEmergencyStop:
991
991
  break
992
992
  assert data.failure.kind == "EStopTriggered"
993
993
 
994
- # ######################################
995
- # Recover from e-stop
996
- # ######################################
994
+ # ######################################
995
+ # Recover from e-stop
996
+ # ######################################
997
997
 
998
- with client.connection():
999
- res_status = client.recovery.recover.recover()
998
+ with client.connection():
999
+ res_status = client.recovery.recover.recover()
1000
1000
 
1001
1001
  def test_estop_sim(self, client_sim: StandardBotsRobot) -> None:
1002
1002
  """Basic test: sim mode
@@ -1324,7 +1324,7 @@ class TestPostMovementPositionArm:
1324
1324
  z=0.707,
1325
1325
  w=0.707,
1326
1326
  )
1327
- initial_tooltip_position = models.Position(x=0.0, y=0.3687, z=1.4618)
1327
+ initial_tooltip_position = models.Position(x=0.0, y=0.3687, z=1.3618)
1328
1328
  target_tooltip_position = models.Position(x=0.1, y=0.4, z=1.3)
1329
1329
  pose_body = models.ArmPositionUpdateRequest(
1330
1330
  kind=models.ArmPositionUpdateRequestKindEnum.TooltipPosition,
@@ -1627,7 +1627,6 @@ class TestGetRecoveryStatus:
1627
1627
  class TestGetCameraStreamRGB:
1628
1628
  """Tests: [GET] `/api/v1/camera/stream/rgb`"""
1629
1629
 
1630
- @pytest.mark.camera_disconnected
1631
1630
  def test_camera_stream_rgb_camera_disconnected(
1632
1631
  self, client_live: StandardBotsRobot
1633
1632
  ) -> None:
@@ -1639,6 +1638,7 @@ class TestGetCameraStreamRGB:
1639
1638
  assert res.isNotOk()
1640
1639
  assert res.status == 503
1641
1640
 
1641
+ @pytest.mark.camera_connected
1642
1642
  def test_basic(self, client_live: StandardBotsRobot) -> None:
1643
1643
  """Basic test to get camera steam RGB"""
1644
1644
  client = client_live
@@ -1674,7 +1674,6 @@ class TestGetCameraStreamRGB:
1674
1674
  class TestPostCameraSettings:
1675
1675
  """Tests: [POST] `/api/v1/camera/settings`"""
1676
1676
 
1677
- @pytest.mark.camera_disconnected
1678
1677
  def test_post_camera_settings_camera_disconnected(
1679
1678
  self, client_live: StandardBotsRobot
1680
1679
  ) -> None:
@@ -1694,6 +1693,7 @@ class TestPostCameraSettings:
1694
1693
  assert res.isNotOk()
1695
1694
  assert res.status == 503
1696
1695
 
1696
+ @pytest.mark.camera_connected
1697
1697
  def test_post_camera_settings(self, client_live: StandardBotsRobot) -> None:
1698
1698
  """Basic test to update settings"""
1699
1699
  client = client_live
@@ -1715,7 +1715,6 @@ class TestPostCameraSettings:
1715
1715
  class TestGetCameraFrameRGB:
1716
1716
  """Tests: [GET] `/api/v1/camera/frame/rgb`"""
1717
1717
 
1718
- @pytest.mark.camera_disconnected
1719
1718
  def test_strem_rgb_camera_disconnected(
1720
1719
  self, client_live: StandardBotsRobot
1721
1720
  ) -> None:
@@ -1737,6 +1736,7 @@ class TestGetCameraFrameRGB:
1737
1736
  assert res.isNotOk()
1738
1737
  assert res.status == 503
1739
1738
 
1739
+ @pytest.mark.camera_connected
1740
1740
  def test_get_color_frame_invalid_payload(
1741
1741
  self, client_live: StandardBotsRobot
1742
1742
  ) -> None:
@@ -1749,6 +1749,7 @@ class TestGetCameraFrameRGB:
1749
1749
  assert res.status == 400
1750
1750
  assert res.data.error == models.ErrorEnum.RequestFailedValidation
1751
1751
 
1752
+ @pytest.mark.camera_connected
1752
1753
  def test_get_color_frame(self, client_live: StandardBotsRobot) -> None:
1753
1754
  """Test get color frame"""
1754
1755
  client = client_live
@@ -1778,7 +1779,6 @@ class TestGetCameraFrameRGB:
1778
1779
  class TestGetCameraIntrinsicsRGB:
1779
1780
  """Tests: [GET] `/api/v1/camera/intrinsics/rgb`"""
1780
1781
 
1781
- @pytest.mark.camera_disconnected
1782
1782
  def test_get_camera_intrinsics_camera_disconnected(
1783
1783
  self, client_live: StandardBotsRobot
1784
1784
  ) -> None:
@@ -1789,6 +1789,7 @@ class TestGetCameraIntrinsicsRGB:
1789
1789
  assert res.isNotOk()
1790
1790
  assert res.status == 503
1791
1791
 
1792
+ @pytest.mark.camera_connected
1792
1793
  def test_get_camera_intrinsics(self, client_live: StandardBotsRobot) -> None:
1793
1794
  """Test to get camera intrinsics"""
1794
1795
 
@@ -1804,7 +1805,6 @@ class TestGetCameraIntrinsicsRGB:
1804
1805
  class TestGetCameraStatus:
1805
1806
  """Tests: [GET] `/api/v1/camera/status`"""
1806
1807
 
1807
- @pytest.mark.camera_disconnected
1808
1808
  def test_get_camera_status_camera_disconnected(
1809
1809
  self, client_live: StandardBotsRobot
1810
1810
  ) -> None:
@@ -1817,6 +1817,7 @@ class TestGetCameraStatus:
1817
1817
  assert isinstance(res.data, models.CameraStatus)
1818
1818
  assert not res.data.connected
1819
1819
 
1820
+ @pytest.mark.camera_connected
1820
1821
  def test_get_camera_status(self, client_live: StandardBotsRobot) -> None:
1821
1822
  """Test to get camera status"""
1822
1823
 
@@ -1832,6 +1833,7 @@ class TestGetCameraStatus:
1832
1833
  class TestGetConnectedCameras:
1833
1834
  """Tests: [GET] `/api/v1/cameras/connected`"""
1834
1835
 
1836
+ @pytest.mark.camera_connected
1835
1837
  def test_get_connected_cameras(self, client_live: StandardBotsRobot) -> None:
1836
1838
  """Test case when camera is disconnected"""
1837
1839
 
@@ -2684,9 +2686,7 @@ class TestPostPosesJointPose:
2684
2686
  client = client_live
2685
2687
  with client.connection():
2686
2688
  body = models.JointPoseRequest(
2687
- pose=models.JointAngles(
2688
- j0=20.0, j1=-30.0, j2=71.0, j3=-130.0, j4=-43.0, j5=60.0
2689
- )
2689
+ pose=models.JointAngles(j0=1.0, j1=-1.0, j2=1.0, j3=1.0, j4=1.0, j5=1.0)
2690
2690
  )
2691
2691
  res = client.poses.construct_pose.joint_pose(body)
2692
2692
  assert not res.isNotOk()
@@ -3322,10 +3322,7 @@ class TestPostMovementPositionArmControlled:
3322
3322
  assert heartbeat_data.event is not None
3323
3323
  assert heartbeat_data.event.kind == models.ArmPositionUpdateKindEnum.Failure
3324
3324
  assert heartbeat_data.event.failure is not None
3325
- assert (
3326
- heartbeat_data.event.failure.reason
3327
- == "Failed to generate a motion plan"
3328
- )
3325
+ assert heartbeat_data.event.failure.reason == "Error while running motion"
3329
3326
 
3330
3327
  def test_move_then_stop_heartbeat(
3331
3328
  self,
@@ -3393,7 +3390,7 @@ class TestPostMovementPositionArmControlled:
3393
3390
  )
3394
3391
 
3395
3392
  assert movement_started > 0, "Movement never started"
3396
- time.sleep(0.25)
3393
+ time.sleep(3)
3397
3394
 
3398
3395
  # Check that the arm has stopped
3399
3396
  res = client.recovery.recover.get_status()
File without changes