standardbots 2.20240212.11__py3-none-any.whl → 2.20241003.41__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.

Potentially problematic release.


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

@@ -53,9 +53,11 @@ class RequestManager:
53
53
 
54
54
  def json_headers(self) -> Dict[str, str]:
55
55
  return {
56
- "Content-Type": "application/json",
57
- "Authorization": "Bearer " + self.token,
58
- "robot_kind": self.robot_kind.value,
56
+ "Content-Type": "application/json",
57
+ "Authorization": "Bearer " + self.token,
58
+ # Include both for backwards-compatibility purposes.
59
+ "robot_kind": self.robot_kind.value,
60
+ "robot-kind": self.robot_kind.value,
59
61
  }
60
62
 
61
63
  def close(self):
@@ -117,6 +119,70 @@ class Default:
117
119
  )
118
120
  )
119
121
 
122
+ def dh_ag_grip(
123
+ self,
124
+ target_diameter: float,
125
+ target_force: float | None,
126
+ target_speed: float | None,
127
+ ):
128
+ """
129
+ Control the DH AG gripper.
130
+ Args:
131
+ - target_diameter: 0.0 - 1.0
132
+ - target_force: 0.2 - 1.0
133
+ - target_speed: 0.01 - 1.0
134
+ """
135
+ return self.control_gripper(
136
+ body=models.GripperCommandRequest(
137
+ kind=models.GripperKindEnum.DhAg,
138
+ dh_ag=models.DHAGGripperCommandRequest(
139
+ target_diameter, target_force, target_speed
140
+ ),
141
+ ),
142
+ )
143
+ def dh_pgc_grip(
144
+ self,
145
+ target_diameter: float,
146
+ target_force: float | None,
147
+ target_speed: float | None,
148
+ ):
149
+ """
150
+ Control the DH PGC gripper.
151
+ Args:
152
+ - target_diameter: 0.0 - 1.0
153
+ - target_force: 0.2 - 1.0
154
+ - target_speed: 0.01 - 1.0
155
+ """
156
+ return self.control_gripper(
157
+ body=models.GripperCommandRequest(
158
+ kind=models.GripperKindEnum.DhPgc,
159
+ dh_pgc=models.DHPGCGripperCommandRequest(
160
+ target_diameter, target_force, target_speed
161
+ ),
162
+ ),
163
+ )
164
+ def dh_cgi_grip(
165
+ self,
166
+ target_diameter: float,
167
+ target_force: float | None,
168
+ target_speed: float | None,
169
+ ):
170
+ """
171
+ Control the DH CGI gripper.
172
+ Args:
173
+ - target_diameter: 0.0 - 1.0
174
+ - target_force: 0.2 - 1.0
175
+ - target_speed: 0.01 - 1.0
176
+ """
177
+ return self.control_gripper(
178
+ body=models.GripperCommandRequest(
179
+ kind=models.GripperKindEnum.DhCgi,
180
+ dh_pgc=models.DHCGIGripperCommandRequest(
181
+ target_diameter, target_force, target_speed
182
+ ),
183
+ ),
184
+ )
185
+
120
186
 
121
187
  def control_gripper(
122
188
  self,
@@ -416,13 +482,17 @@ class Movement:
416
482
  position: models.Position,
417
483
  orientation: models.Orientation,
418
484
  reference_frame: str = 'base',
419
- axis_alignment: str = 'base'
485
+ axis_alignment: str = 'base',
486
+ local_accuracy_calibration: str | None = None,
487
+ movement_kind: models.MovementKindEnum | None = models.MovementKindEnum.Joint,
420
488
  ):
421
489
  return self.move_tooltip(
422
490
  position=position,
423
491
  orientation=orientation,
424
492
  reference_frame=reference_frame,
425
- axis_alignment=axis_alignment
493
+ axis_alignment=axis_alignment,
494
+ local_accuracy_calibration=local_accuracy_calibration,
495
+ movement_kind=movement_kind
426
496
  )
427
497
 
428
498
  def move_tooltip(
@@ -430,7 +500,9 @@ class Movement:
430
500
  position: models.Position,
431
501
  orientation: models.Orientation,
432
502
  reference_frame: str = 'base',
433
- axis_alignment: str = 'base'
503
+ axis_alignment: str = 'base',
504
+ local_accuracy_calibration: str | None = None,
505
+ movement_kind: models.MovementKindEnum | None = models.MovementKindEnum.Joint
434
506
  ):
435
507
  """Move tooltip of robot to specified position
436
508
  """
@@ -440,6 +512,7 @@ class Movement:
440
512
  position=position,
441
513
  orientation=orientation,
442
514
  reference_frame=reference_frame,
515
+ local_accuracy_calibration=local_accuracy_calibration,
443
516
  axis_alignment=axis_alignment,
444
517
  ),
445
518
  )
@@ -525,6 +598,582 @@ class Movement:
525
598
  self.brakes = Movement.Brakes(request_manager)
526
599
  self.position = Movement.Position(request_manager)
527
600
 
601
+ class Camera:
602
+ _request_manager: RequestManager
603
+ class Data:
604
+ def __init__(self, request_manager: RequestManager):
605
+ self._request_manager = request_manager
606
+
607
+
608
+ def get_color_frame(
609
+ self,
610
+ body: models.CameraFrameRequest,
611
+ ) -> Response[
612
+ None,
613
+ None
614
+ ]:
615
+ """
616
+ Retrieve the latest RGB frame from the camera.
617
+ """
618
+ path = "/api/v1/camera/frame/rgb"
619
+ response = self._request_manager.request(
620
+ "GET",
621
+ path,
622
+ headers=self._request_manager.json_headers(),
623
+ body=json.dumps(models.serialize_camera_frame_request(body)),
624
+ )
625
+ parsed = None
626
+
627
+ is_user_error = response.status >= 400 and response.status < 500
628
+ is_unavailable = response.status == 503
629
+ if parsed is None and (is_user_error or is_unavailable):
630
+ parsed = models.parse_error_response(json.loads(response.data))
631
+
632
+ return Response(
633
+ parsed,
634
+ response.status,
635
+ response
636
+ )
637
+
638
+ def get_camera_intrinsics_color(
639
+ self,
640
+ ) -> Response[
641
+ None,
642
+ None
643
+ ]:
644
+ """
645
+ Retrieve the intrinsic parameters for the color camera.
646
+ """
647
+ path = "/api/v1/camera/intrinsics/rgb"
648
+ response = self._request_manager.request(
649
+ "GET",
650
+ path,
651
+ headers=self._request_manager.json_headers(),
652
+ )
653
+ parsed = None
654
+
655
+ is_user_error = response.status >= 400 and response.status < 500
656
+ is_unavailable = response.status == 503
657
+ if parsed is None and (is_user_error or is_unavailable):
658
+ parsed = models.parse_error_response(json.loads(response.data))
659
+
660
+ return Response(
661
+ parsed,
662
+ response.status,
663
+ response
664
+ )
665
+
666
+ def get_camera_stream(
667
+ self,
668
+ ) -> Response[
669
+ None,
670
+ None
671
+ ]:
672
+ """
673
+ Retrieve the latest RGB frame from the camera.
674
+ """
675
+ path = "/api/v1/camera/stream/rgb"
676
+ response = self._request_manager.request(
677
+ "GET",
678
+ path,
679
+ headers=self._request_manager.json_headers(),
680
+ preload_content=False,
681
+ )
682
+ parsed = None
683
+
684
+ is_user_error = response.status >= 400 and response.status < 500
685
+ is_unavailable = response.status == 503
686
+ if parsed is None and (is_user_error or is_unavailable):
687
+ parsed = models.parse_error_response(json.loads(response.data))
688
+
689
+ return Response(
690
+ parsed,
691
+ response.status,
692
+ response
693
+ )
694
+
695
+ class Settings:
696
+ def __init__(self, request_manager: RequestManager):
697
+ self._request_manager = request_manager
698
+
699
+
700
+ def set_camera_settings(
701
+ self,
702
+ body: models.CameraSettings,
703
+ ) -> Response[
704
+ None,
705
+ None
706
+ ]:
707
+ """
708
+ Set the camera settings.
709
+ """
710
+ path = "/api/v1/camera/settings"
711
+ response = self._request_manager.request(
712
+ "POST",
713
+ path,
714
+ headers=self._request_manager.json_headers(),
715
+ body=json.dumps(models.serialize_camera_settings(body)),
716
+ )
717
+ parsed = None
718
+
719
+ is_user_error = response.status >= 400 and response.status < 500
720
+ is_unavailable = response.status == 503
721
+ if parsed is None and (is_user_error or is_unavailable):
722
+ parsed = models.parse_error_response(json.loads(response.data))
723
+
724
+ return Response(
725
+ parsed,
726
+ response.status,
727
+ response
728
+ )
729
+
730
+ data: Data
731
+ settings: Settings
732
+
733
+ def __init__(self, request_manager: RequestManager):
734
+ self._request_manager = request_manager
735
+ self.data = Camera.Data(request_manager)
736
+ self.settings = Camera.Settings(request_manager)
737
+
738
+ class Faults:
739
+ _request_manager: RequestManager
740
+ class UserFaults:
741
+ def __init__(self, request_manager: RequestManager):
742
+ self._request_manager = request_manager
743
+
744
+
745
+ def trigger_user_fault(
746
+ self,
747
+ body: models.TriggerFaultRequest,
748
+ ) -> Response[
749
+ Union[
750
+ models.ErrorResponse,
751
+ models.ErrorResponse,
752
+ None
753
+ ],
754
+ None
755
+ ]:
756
+ """
757
+ Trigger user faults for routine
758
+
759
+ """
760
+ path = "/api/v1/faults/user-fault"
761
+ response = self._request_manager.request(
762
+ "POST",
763
+ path,
764
+ headers=self._request_manager.json_headers(),
765
+ body=json.dumps(models.serialize_trigger_fault_request(body)),
766
+ )
767
+ parsed = None
768
+ if response.status == 400:
769
+ parsed = models.parse_error_response(json.loads(response.data))
770
+
771
+ is_user_error = response.status >= 400 and response.status < 500
772
+ is_unavailable = response.status == 503
773
+ if parsed is None and (is_user_error or is_unavailable):
774
+ parsed = models.parse_error_response(json.loads(response.data))
775
+
776
+ return Response(
777
+ parsed,
778
+ response.status,
779
+ response
780
+ )
781
+
782
+ user_faults: UserFaults
783
+
784
+ def __init__(self, request_manager: RequestManager):
785
+ self._request_manager = request_manager
786
+ self.user_faults = Faults.UserFaults(request_manager)
787
+
788
+ class ChatGPT:
789
+ _request_manager: RequestManager
790
+ class Data:
791
+ def __init__(self, request_manager: RequestManager):
792
+ self._request_manager = request_manager
793
+
794
+
795
+ def speech_to_text(
796
+ self,
797
+ body: models.SpeechToTextRequest,
798
+ ) -> Response[
799
+ None,
800
+ None
801
+ ]:
802
+ """
803
+ Convert speech to text.
804
+ """
805
+ path = "/api/v1/internal-only/speech-to-text"
806
+ response = self._request_manager.request(
807
+ "POST",
808
+ path,
809
+ headers=self._request_manager.json_headers(),
810
+ body=json.dumps(models.serialize_speech_to_text_request(body)),
811
+ )
812
+ parsed = None
813
+
814
+ is_user_error = response.status >= 400 and response.status < 500
815
+ is_unavailable = response.status == 503
816
+ if parsed is None and (is_user_error or is_unavailable):
817
+ parsed = models.parse_error_response(json.loads(response.data))
818
+
819
+ return Response(
820
+ parsed,
821
+ response.status,
822
+ response
823
+ )
824
+
825
+ def text_to_skill(
826
+ self,
827
+ body: models.TextToSkillRequest,
828
+ ) -> Response[
829
+ None,
830
+ None
831
+ ]:
832
+ """
833
+ Convert text to a skill.
834
+ """
835
+ path = "/api/v1/internal-only/text-to-skill"
836
+ response = self._request_manager.request(
837
+ "POST",
838
+ path,
839
+ headers=self._request_manager.json_headers(),
840
+ body=json.dumps(models.serialize_text_to_skill_request(body)),
841
+ )
842
+ parsed = None
843
+
844
+ is_user_error = response.status >= 400 and response.status < 500
845
+ is_unavailable = response.status == 503
846
+ if parsed is None and (is_user_error or is_unavailable):
847
+ parsed = models.parse_error_response(json.loads(response.data))
848
+
849
+ return Response(
850
+ parsed,
851
+ response.status,
852
+ response
853
+ )
854
+
855
+ data: Data
856
+
857
+ def __init__(self, request_manager: RequestManager):
858
+ self._request_manager = request_manager
859
+ self.data = ChatGPT.Data(request_manager)
860
+
861
+ class IO:
862
+ _request_manager: RequestManager
863
+ class Control:
864
+ def __init__(self, request_manager: RequestManager):
865
+ self._request_manager = request_manager
866
+
867
+
868
+ def update_io_state(
869
+ self,
870
+ body: models.IOStateUpdateRequest,
871
+ ) -> Response[
872
+ Union[
873
+ models.IOStateResponse,
874
+ models.ErrorResponse,
875
+ models.ErrorResponse,
876
+ None
877
+ ],
878
+ models.IOStateResponse
879
+ ]:
880
+ """
881
+ Updates the state of I/O based on the provided action (&#x27;high&#x27; or &#x27;low&#x27;).
882
+ """
883
+ path = "/api/v1/io"
884
+ response = self._request_manager.request(
885
+ "POST",
886
+ path,
887
+ headers=self._request_manager.json_headers(),
888
+ body=json.dumps(models.serialize_io_state_update_request(body)),
889
+ )
890
+ parsed = None
891
+ if response.status == 200:
892
+ parsed = models.parse_io_state_response(json.loads(response.data))
893
+ if response.status == 400:
894
+ parsed = models.parse_error_response(json.loads(response.data))
895
+
896
+ is_user_error = response.status >= 400 and response.status < 500
897
+ is_unavailable = response.status == 503
898
+ if parsed is None and (is_user_error or is_unavailable):
899
+ parsed = models.parse_error_response(json.loads(response.data))
900
+
901
+ return Response(
902
+ parsed,
903
+ response.status,
904
+ response
905
+ )
906
+
907
+ class Status:
908
+ def __init__(self, request_manager: RequestManager):
909
+ self._request_manager = request_manager
910
+
911
+
912
+ def get_io_state(
913
+ self,
914
+ ) -> Response[
915
+ Union[
916
+ models.IOStateResponse,
917
+ models.ErrorResponse,
918
+ None
919
+ ],
920
+ models.IOStateResponse
921
+ ]:
922
+ """
923
+ Retrieves the current state of I/O.
924
+ """
925
+ path = "/api/v1/io"
926
+ response = self._request_manager.request(
927
+ "GET",
928
+ path,
929
+ headers=self._request_manager.json_headers(),
930
+ )
931
+ parsed = None
932
+ if response.status == 200:
933
+ parsed = models.parse_io_state_response(json.loads(response.data))
934
+
935
+ is_user_error = response.status >= 400 and response.status < 500
936
+ is_unavailable = response.status == 503
937
+ if parsed is None and (is_user_error or is_unavailable):
938
+ parsed = models.parse_error_response(json.loads(response.data))
939
+
940
+ return Response(
941
+ parsed,
942
+ response.status,
943
+ response
944
+ )
945
+
946
+ control: Control
947
+ status: Status
948
+
949
+ def __init__(self, request_manager: RequestManager):
950
+ self._request_manager = request_manager
951
+ self.control = IO.Control(request_manager)
952
+ self.status = IO.Status(request_manager)
953
+
954
+ class General:
955
+ _request_manager: RequestManager
956
+ class Joints:
957
+ def __init__(self, request_manager: RequestManager):
958
+ self._request_manager = request_manager
959
+
960
+
961
+ def get_joints_state(
962
+ self,
963
+ ) -> Response[
964
+ Union[
965
+ models.JointsStateResponse,
966
+ models.ErrorResponse,
967
+ None
968
+ ],
969
+ models.JointsStateResponse
970
+ ]:
971
+ """
972
+ Retrieves information about the state of each joint
973
+ """
974
+ path = "/api/v1/joints"
975
+ response = self._request_manager.request(
976
+ "GET",
977
+ path,
978
+ headers=self._request_manager.json_headers(),
979
+ )
980
+ parsed = None
981
+ if response.status == 200:
982
+ parsed = models.parse_joints_state_response(json.loads(response.data))
983
+
984
+ is_user_error = response.status >= 400 and response.status < 500
985
+ is_unavailable = response.status == 503
986
+ if parsed is None and (is_user_error or is_unavailable):
987
+ parsed = models.parse_error_response(json.loads(response.data))
988
+
989
+ return Response(
990
+ parsed,
991
+ response.status,
992
+ response
993
+ )
994
+
995
+ joints: Joints
996
+
997
+ def __init__(self, request_manager: RequestManager):
998
+ self._request_manager = request_manager
999
+ self.joints = General.Joints(request_manager)
1000
+
1001
+ class Recovery:
1002
+ _request_manager: RequestManager
1003
+ class Recover:
1004
+ def __init__(self, request_manager: RequestManager):
1005
+ self._request_manager = request_manager
1006
+
1007
+
1008
+ def recover(
1009
+ self,
1010
+ ) -> Response[
1011
+ Union[
1012
+ models.FailureStateResponse,
1013
+ models.ErrorResponse,
1014
+ models.ErrorResponse,
1015
+ None
1016
+ ],
1017
+ models.FailureStateResponse
1018
+ ]:
1019
+ """
1020
+ Attempts to recover the robot from a fault state. Inspect the response to determine if additional recovery actions are required.
1021
+
1022
+ """
1023
+ path = "/api/v1/recovery/recover"
1024
+ response = self._request_manager.request(
1025
+ "POST",
1026
+ path,
1027
+ headers=self._request_manager.json_headers(),
1028
+ )
1029
+ parsed = None
1030
+ if response.status == 200:
1031
+ parsed = models.parse_failure_state_response(json.loads(response.data))
1032
+ if response.status == 400:
1033
+ parsed = models.parse_error_response(json.loads(response.data))
1034
+
1035
+ is_user_error = response.status >= 400 and response.status < 500
1036
+ is_unavailable = response.status == 503
1037
+ if parsed is None and (is_user_error or is_unavailable):
1038
+ parsed = models.parse_error_response(json.loads(response.data))
1039
+
1040
+ return Response(
1041
+ parsed,
1042
+ response.status,
1043
+ response
1044
+ )
1045
+
1046
+ def get_status(
1047
+ self,
1048
+ ) -> Response[
1049
+ Union[
1050
+ models.FailureStateResponse,
1051
+ models.ErrorResponse,
1052
+ None
1053
+ ],
1054
+ models.FailureStateResponse
1055
+ ]:
1056
+ """
1057
+ Get the robot&#x27;s recovery status.
1058
+
1059
+ """
1060
+ path = "/api/v1/recovery/status"
1061
+ response = self._request_manager.request(
1062
+ "GET",
1063
+ path,
1064
+ headers=self._request_manager.json_headers(),
1065
+ )
1066
+ parsed = None
1067
+ if response.status == 200:
1068
+ parsed = models.parse_failure_state_response(json.loads(response.data))
1069
+
1070
+ is_user_error = response.status >= 400 and response.status < 500
1071
+ is_unavailable = response.status == 503
1072
+ if parsed is None and (is_user_error or is_unavailable):
1073
+ parsed = models.parse_error_response(json.loads(response.data))
1074
+
1075
+ return Response(
1076
+ parsed,
1077
+ response.status,
1078
+ response
1079
+ )
1080
+
1081
+ recover: Recover
1082
+
1083
+ def __init__(self, request_manager: RequestManager):
1084
+ self._request_manager = request_manager
1085
+ self.recover = Recovery.Recover(request_manager)
1086
+
1087
+ class ROS:
1088
+ _request_manager: RequestManager
1089
+ class Control:
1090
+ def __init__(self, request_manager: RequestManager):
1091
+ self._request_manager = request_manager
1092
+
1093
+
1094
+ def update_ros_control_state(
1095
+ self,
1096
+ body: models.ROSControlUpdateRequest,
1097
+ ) -> Response[
1098
+ Union[
1099
+ models.ROSControlStateResponse,
1100
+ models.ErrorResponse,
1101
+ None
1102
+ ],
1103
+ models.ROSControlStateResponse
1104
+ ]:
1105
+ """
1106
+ Updates the state of ROS control based on the provided action (&#x27;enable&#x27; or &#x27;disable&#x27;).
1107
+ """
1108
+ path = "/api/v1/movement/ros/state"
1109
+ response = self._request_manager.request(
1110
+ "POST",
1111
+ path,
1112
+ headers=self._request_manager.json_headers(),
1113
+ body=json.dumps(models.serialize_ros_control_update_request(body)),
1114
+ )
1115
+ parsed = None
1116
+ if response.status == 200:
1117
+ parsed = models.parse_ros_control_state_response(json.loads(response.data))
1118
+
1119
+ is_user_error = response.status >= 400 and response.status < 500
1120
+ is_unavailable = response.status == 503
1121
+ if parsed is None and (is_user_error or is_unavailable):
1122
+ parsed = models.parse_error_response(json.loads(response.data))
1123
+
1124
+ return Response(
1125
+ parsed,
1126
+ response.status,
1127
+ response
1128
+ )
1129
+
1130
+ class Status:
1131
+ def __init__(self, request_manager: RequestManager):
1132
+ self._request_manager = request_manager
1133
+
1134
+
1135
+ def get_ros_control_state(
1136
+ self,
1137
+ ) -> Response[
1138
+ Union[
1139
+ models.ROSControlStateResponse,
1140
+ models.ErrorResponse,
1141
+ None
1142
+ ],
1143
+ models.ROSControlStateResponse
1144
+ ]:
1145
+ """
1146
+ Retrieves the current state of ROS control.
1147
+ """
1148
+ path = "/api/v1/movement/ros/state"
1149
+ response = self._request_manager.request(
1150
+ "GET",
1151
+ path,
1152
+ headers=self._request_manager.json_headers(),
1153
+ )
1154
+ parsed = None
1155
+ if response.status == 200:
1156
+ parsed = models.parse_ros_control_state_response(json.loads(response.data))
1157
+
1158
+ is_user_error = response.status >= 400 and response.status < 500
1159
+ is_unavailable = response.status == 503
1160
+ if parsed is None and (is_user_error or is_unavailable):
1161
+ parsed = models.parse_error_response(json.loads(response.data))
1162
+
1163
+ return Response(
1164
+ parsed,
1165
+ response.status,
1166
+ response
1167
+ )
1168
+
1169
+ control: Control
1170
+ status: Status
1171
+
1172
+ def __init__(self, request_manager: RequestManager):
1173
+ self._request_manager = request_manager
1174
+ self.control = ROS.Control(request_manager)
1175
+ self.status = ROS.Status(request_manager)
1176
+
528
1177
  class RoutineEditor:
529
1178
  _request_manager: RequestManager
530
1179
  class Routines:
@@ -705,7 +1354,7 @@ class RoutineEditor:
705
1354
 
706
1355
  def load(
707
1356
  self,
708
- variable_id: str,
1357
+ variable_name: str,
709
1358
  ) -> Response[
710
1359
  Union[
711
1360
  models.RuntimeVariable,
@@ -717,8 +1366,8 @@ class RoutineEditor:
717
1366
  """
718
1367
  Returns current state of a variable
719
1368
  """
720
- path = "/api/v1/routine-editor/variables/{variable_id}"
721
- path = path.replace("{variable_id}", str(variable_id))
1369
+ path = "/api/v1/routine-editor/variables/{variable_name}"
1370
+ path = path.replace("{variable_name}", str(variable_name))
722
1371
  response = self._request_manager.request(
723
1372
  "GET",
724
1373
  path,
@@ -742,7 +1391,7 @@ class RoutineEditor:
742
1391
  def update(
743
1392
  self,
744
1393
  body: models.RuntimeVariable,
745
- variable_id: str,
1394
+ variable_name: str,
746
1395
  ) -> Response[
747
1396
  Union[
748
1397
  models.RuntimeVariable,
@@ -754,8 +1403,8 @@ class RoutineEditor:
754
1403
  """
755
1404
  Update the value of a variable
756
1405
  """
757
- path = "/api/v1/routine-editor/variables/{variable_id}"
758
- path = path.replace("{variable_id}", str(variable_id))
1406
+ path = "/api/v1/routine-editor/variables/{variable_name}"
1407
+ path = path.replace("{variable_name}", str(variable_name))
759
1408
  response = self._request_manager.request(
760
1409
  "POST",
761
1410
  path,
@@ -916,6 +1565,13 @@ class StandardBotsRobot(Default):
916
1565
  RobotKind = RobotKind
917
1566
 
918
1567
  movement: Movement
1568
+ camera: Camera
1569
+ faults: Faults
1570
+ chat_gpt: ChatGPT
1571
+ io: IO
1572
+ general: General
1573
+ recovery: Recovery
1574
+ ros: ROS
919
1575
  routine_editor: RoutineEditor
920
1576
  status: Status
921
1577
  def __init__(
@@ -932,6 +1588,13 @@ class StandardBotsRobot(Default):
932
1588
  robot_kind=RobotKind(robot_kind),
933
1589
  ))
934
1590
  self.movement = Movement(self._request_manager)
1591
+ self.camera = Camera(self._request_manager)
1592
+ self.faults = Faults(self._request_manager)
1593
+ self.chat_gpt = ChatGPT(self._request_manager)
1594
+ self.io = IO(self._request_manager)
1595
+ self.general = General(self._request_manager)
1596
+ self.recovery = Recovery(self._request_manager)
1597
+ self.ros = ROS(self._request_manager)
935
1598
  self.routine_editor = RoutineEditor(self._request_manager)
936
1599
  self.status = Status(self._request_manager)
937
1600