diff --git a/README.md b/README.md
index 5b74502..344faa0 100644
--- a/README.md
+++ b/README.md
@@ -2,46 +2,49 @@
### [](https://github.com/kubeedge/robosdk)
+Welcome to RoboSDK, an open-source cloud-native robotics toolchain designed to empower developers in building cutting-edge robotics applications. This README provides an overview of the project and its objectives, guiding developers on how to get started, and encouraging community engagement.
-### What is RoboSDK
+**Table of Contents**
+1. [Introduction](#introduction)
+2. [Features](#features)
+3. [Architecture](#architecture)
+4. [Getting Started](#getting-started)
+5. [Usage Examples](#usage-examples)
+6. [Community](#community)
+7. [Cite Us](#cite-us)
+8. [Roadmap](#roadmap)
+9. [Contributing](#contributing)
+10. [License](#license)
-`RoboSDK` is a light weight, high-level interface which provides hardware independent APIs for robotic control and perception.
-The goal of this project is to abstract away the low-level controls for developing APPs that runs on an industrial robot in an easy-to-use way.
+
+### Introduction
+
+`RoboSDK` is a cloud-native robotics development platform that aims to simplify and democratize the creation of sophisticated robotics applications. It provides a hardware-agnostic environment and middleware-based approach to seamlessly integrate cloud services with various robot operating systems.
+
+`RoboSDK` empowers developers of all skill levels to innovate and unleash the potential of cloud-native robotics in diverse industries.
+
+The goal of this project is to abstract away the low-level controls for developing APPs that runs on robots in an easy-to-use way.
### Features
-`RoboSDK` provide the following features:
+- **Hardware Abstraction**: Bridge the gap between diverse robot hardware and simplify integration with standardized interfaces.
+- **Middleware Compatibility**: Seamlessly interact with various robot operating systems, including [ROS 1](https://wiki.ros.org/), [ROS 2](http://docs.ros.org/), and [OpenHarmony](https://www.openharmony.cn/).
+- **Cloud Integration**: Access powerful cloud resources for advanced robotics functionalities, such as `Object Storage Service` and `Real-Time Communication`.
+- **Simulators Interfacing**: Interact with simulators such as [Gazebo](http://gazebosim.org/) and [Pybullet](https://pybullet.org/wordpress/).
+- **Factory Registry**: Encourage modular contributions by providing a user-friendly development experience.
-- Defining the Running World
- - A `World` represent an environment which the robot launch, such as interactive maps, active objects and scenarios.
- - `simulator`: it provides some predefined scenarios such as Gazebo, and the reusable wheels for building new `World`.
-
-- Sensor-Based Control for Registered Robots
- - Object-oriented, unified interface for equivalent sensors, such as : `Camera`, `Lidar`, `IMU` and `Audio`.
- Therefore, they are guaranteed to have the same interface defined by the base class, for example,
- `Camera` would have `get_rgb`, `get_depth` as its member function, and their behavior would be the same across hardware.
- - A `Robot` instance consists of multiple components of sensors which were extended the `BaseClass` respectively. `Robot` and `Sensor` is one-to-many.
- - A `Robot` is controlled by invoking the `Sensor` interface. The robots are managed by combining multiple configurations of each sensor.
- - Interconnection with Vendor-defined interface, like: socket-base gait change.
-
-- Plug-in-and-play Algorithms
- - Localize
- - Perception
- - Navigation
- - Cloud-Edge Service
-
-- Robot Operating System Backend mapping
- ```text
- It provides a full-stack abstraction for Robot Operating System, such as message manager.
- ```
-
- - Ros1 [stable]
- - Ros2 [rc]
- - openHarmony [alpha]
+
+### Architecture
+
+
-### Installation
+### Getting Started
+
+Let’s walk through setting up a robot with a camera to complete a simple application development based on `RoboSDK`.
+
+Installation
- Prerequisites
- Robot Operating System: such as [Ros noetic](http://wiki.ros.org/noetic/installation/ubuntu)
@@ -67,7 +70,7 @@ The goal of this project is to abstract away the low-level controls for developi
.\robo_venv\Scripts\activate
```
-- Install RoboSDK
+- Install `RoboSDK`
```sh
# Git Clone the whole source code.
@@ -79,23 +82,102 @@ The goal of this project is to abstract away the low-level controls for developi
# Install the pip package
pip3 install dist/robosdk*.whl
```
-
-### Show Cases
+
+
+
+Simple application development
+
+#### Transmitting Robot's vision to the cloud
+
+- Step 1: Configure Robot with yaml file
+
+ ```yaml
+ # demo.yaml
+ name: "demo"
+ environment:
+ backend: "ros1"
+ requirement:
+ - rospy
+ - rostopic
+ - roslib
+ sensors:
+ camera:
+ - name: "cam1"
+ config: "simplecamera"
+ rgb:
+ target: "/usb_cam_1/image_raw"
+ actual_hz: 10
+ origin_hz: 30
+ is_compressed: false
+ info:
+ target: "/usb_cam_1/camera_info"
+ control:
+ - motion:
+ name: "ros_cmd_vel"
+ config: "cmd_vel"
+ ```
+
+- Step 2: Write a simple application
+
+ ```python
+ # demo.py
+
+ import cv2
+ import time
+
+ from robosdk.core.robot import Robot
+ from robosdk.common.fileops import FileOps
+
+
+ def main():
+ robot = Robot(name="my_robot", config="demo")
+ robot.connect()
+
+ total_img = 10
+ wait_time = .2
+ upload_target = "s3://test"
+
+ while total_img:
+ time.sleep(wait_time)
+
+ rgb, timer = robot.camera.get_rgb()
+ if rgb is None:
+ continue
+
+ _ = cv2.imwrite(f"./{timer}.png", rgb)
+ FileOps.upload(f"./{timer}.png", f"{upload_target}/{timer}.png")
+
+ total_img -= 1
+ ```
+
+- Step 3: Run the application
+
+ ```sh
+
+ source ./robo_venv/bin/activate
+ source /opt/ros/noetic/setup.bash
+
+ python3 demo.py
+ ```
+
+
+### Usage Examples
- Case I - [Legged-Robot Auto Gait Change](./examples/ysc_x20/auto_gait_change)
- Case II - [Arm-Robot Teleoperation](./examples/scout_arm/teleoperation)
-### Supported
+### Community
-As we are currently fully tested in the following Robots/sensors, which is considered to be well supported :
+Join the KubeEdge Sig Robotics community! Engage in discussions, share ideas, and collaborate with like-minded developers. Feel free to reach out to us through [this documents](https://github.com/kubeedge/community/tree/master/sig-robotics).
-#### Robot
- - [x20](https://www.deeprobotics.cn/products_jy_3.html)
- - [scout](https://global.agilex.ai/products/scout-mini)
### [Cite Us](./CITATION)
+### [Roadmap](./docs/source/proposals/roadmap.md)
+
+### [Contributing](./CONTRIBUTING.md)
+
### License
Copyright 2021 The KubeEdge Authors. All rights reserved.
diff --git a/docs/source/_static/architecture.png b/docs/source/_static/architecture.png
new file mode 100644
index 0000000..4f7e33a
Binary files /dev/null and b/docs/source/_static/architecture.png differ
diff --git a/docs/source/proposals/README.md b/docs/source/proposals/README.md
new file mode 100644
index 0000000..6efeac7
--- /dev/null
+++ b/docs/source/proposals/README.md
@@ -0,0 +1,21 @@
+**RoboSDK - Empowering Cloud-Native Robotics Development**
+
+
+
+Welcome to `RoboSDK`, an open-source cloud-native robotics toolchain designed to empower developers in building cutting-edge robotics applications. This README provides an overview of the project and its objectives, guiding developers on how to get started, and encouraging community engagement.
+
+`RoboSDK` aims to address these challenges and provide developers with a unified platform for cloud-native robotics development.
+
+Here provides a proposal to `RoboSDK`, comprises the following key sections:
+
+1. **Introduction:** An overview to `RoboSDK`, goals, significance and concepts in our project.
+
+2. **Project Design:** An in-depth explanation of `RoboSDK`'s architecture, highlighting its hardware abstraction layer, cloud service integration, and support for different robot operating systems.
+
+3. **Comparison:** A detailed comparison between `RoboSDK` and the existing reference work, emphasizing the advantages and innovations `RoboSDK` brings to the field.
+
+4. **Value Description:** A breakdown of the value `RoboSDK` brings to the cloud computing, robotics industry, and developers of all levels of expertise.
+
+5. **Roadmap:** A forward-looking plan outlining the project's goals, upcoming features, and enhancements for `RoboSDK`.
+
+6. **References:** A list of references used in our project.
\ No newline at end of file
diff --git a/docs/source/proposals/comparison.md b/docs/source/proposals/comparison.md
new file mode 100644
index 0000000..483c46f
--- /dev/null
+++ b/docs/source/proposals/comparison.md
@@ -0,0 +1,64 @@
+# Detailed Comparison: RoboSDK vs. Existing Reference Works
+
+In this section, we will conduct a comprehensive comparison between `RoboSDK` and three prominent existing reference works: [NVIDIA Isaac SDK](https://developer.nvidia.com/isaac-sdk), [AWS IoT SDK](https://docs.aws.amazon.com/iot/latest/developerguide/iot-sdks.html), and [rospy](http://wiki.ros.org/rospy). By highlighting the advantages and innovations that `RoboSDK` brings to the field, we aim to demonstrate its unique position in the cloud-native robotics landscape.
+
+## 1. NVIDIA Isaac SDK
+
+### Hardware Abstraction
+- NVIDIA Isaac SDK provides hardware abstraction for NVIDIA-specific robotic platforms, offering optimized performance for their hardware ecosystem.
+- In contrast, RoboSDK offers a more generic hardware abstraction layer, enabling seamless integration with a wide range of robot platforms, not limited to any specific hardware vendor.
+
+### Cloud Service Integration
+- NVIDIA Isaac SDK primarily focuses on integration with NVIDIA's cloud services and edge computing solutions.
+- RoboSDK, on the other hand, adopts a middleware-based approach to integrate with a broader array of cloud services, including the ability to seamlessly interface with RoboArtisan's cloud offerings (RoboOMS and RoboSS).
+
+### Support for Robot Operating Systems
+- NVIDIA Isaac SDK is optimized for ROS 2 and tightly coupled with the NVIDIA Jetson platform.
+- RoboSDK takes a platform-agnostic approach, supporting both ROS 1 and ROS 2, as well as other robot operating systems, such as Harmony, to cater to the diverse needs of developers.
+
+### Advantages of RoboSDK
+- RoboSDK's generic hardware abstraction layer ensures compatibility with various robot platforms, enabling developers to deploy their applications across a wider range of robots.
+- The middleware-based cloud service integration facilitates seamless utilization of RoboArtisan's cloud resources, streamlining task management and data storage.
+- Support for multiple robot operating systems allows developers to leverage RoboSDK's capabilities regardless of their preferred robot framework.
+
+## 2. AWS IoT SDK
+
+### Cloud-Native Capabilities
+- AWS IoT SDK is a comprehensive toolkit for cloud-native development, designed primarily for IoT applications.
+- RoboSDK, being tailored for robotics, focuses on addressing the specific challenges and requirements in the cloud-native robotics domain, providing dedicated robot-centric features.
+
+### Robot-Specific Abstraction
+- AWS IoT SDK offers general-purpose abstractions for IoT devices, but it lacks specialized features for robots' unique characteristics.
+- RoboSDK's hardware abstraction layer is specifically designed to cater to robot-specific needs, providing interfaces for robot actuators, sensors, and communication channels.
+
+### Middleware for RoboArtisan Cloud Services
+- While AWS IoT SDK offers cloud service integration, it does not have built-in middleware for integrating with RoboArtisan's cloud services, limiting its direct compatibility with RoboOMS and RoboSS.
+- RoboSDK's middleware-based approach bridges this gap, enabling developers to interact seamlessly with RoboArtisan's cloud resources.
+
+### Advantages of RoboSDK
+- RoboSDK's specialized focus on cloud-native robotics ensures a more tailored and optimized development experience for robot applications.
+- The robot-specific abstraction layer enhances the efficiency of robot operations, enabling developers to focus on creating sophisticated robot behaviors.
+- Middleware integration with RoboArtisan cloud services enhances data management and task coordination, streamlining the development process.
+
+## 3. rospy
+
+### ROS-Centric Approach
+- rospy is a Python library and part of the ROS ecosystem, offering a Python interface for ROS nodes.
+- RoboSDK, while supporting ROS 1 and ROS 2, provides a higher-level interface that abstracts away the complexities of ROS, simplifying the development process for developers who are not deeply familiar with ROS.
+
+### Cloud Service Integration
+- rospy does not natively integrate with cloud services, requiring developers to implement their own integration solutions.
+- RoboSDK's middleware-based cloud service integration provides a unified interface for utilizing cloud resources, including RoboArtisan's cloud offerings.
+
+### Hardware Abstraction
+- rospy does not offer a dedicated hardware abstraction layer, leaving developers to deal with hardware integration challenges themselves.
+- RoboSDK's hardware abstraction layer provides a consistent and easy-to-use interface for accessing robot hardware, regardless of the underlying robot platform.
+
+### Advantages of RoboSDK
+- RoboSDK's higher-level interface abstracts away the complexities of ROS, making it accessible to developers from various backgrounds.
+- The middleware-based cloud service integration simplifies the utilization of cloud resources, making it more convenient for developers to leverage cloud-native capabilities.
+- The hardware abstraction layer saves development time and effort by providing a consistent and unified API for interacting with diverse robot hardware.
+
+## Conclusion
+
+RoboSDK stands out as a dedicated, cloud-native robotics framework that offers a unique set of advantages compared to existing reference works such as NVIDIA Isaac SDK, AWS IoT SDK, and rospy. Its generic hardware abstraction, middleware-based cloud service integration, and support for various robot operating systems set it apart as an innovative solution for cloud-native robot application development. By leveraging RoboSDK's capabilities, developers can unlock new possibilities in the field of cloud-native robotics and build cutting-edge applications that transform industries and drive the future of robotics.
\ No newline at end of file
diff --git a/docs/source/proposals/introduction.md b/docs/source/proposals/introduction.md
new file mode 100644
index 0000000..6570dc1
--- /dev/null
+++ b/docs/source/proposals/introduction.md
@@ -0,0 +1,37 @@
+# Introduction
+
+`RoboSDK` is an open-source project that aims to democratize robotics development by providing developers with convenient access to robot datasets, cloud resources, and hardware abstraction. Our mission is to lower the barriers to entry in the robotics domain and enable ambitious projects at all levels of expertise. By leveraging the power of cloud-native technologies, `RoboSDK` enhances the capabilities of robots and opens up new possibilities for applications in various industries, including manufacturing, healthcare, logistics, and more.
+
+## Significance
+
+Cloud-native robotics is revolutionizing the robotics industry, enabling robots to adapt and learn from real-world experiences continuously. With `RoboSDK`, we seek to drive this transformation by providing a comprehensive and user-friendly framework for cloud-native robotics application development.
+
+Cloud-native robotics is a cutting-edge approach that leverages cloud computing and services to enhance the capabilities of robots. By offloading computation and data storage to the cloud, robots can access vast amounts of data, powerful machine learning algorithms, and computational resources, enabling them to perform complex tasks and make data-driven decisions. This approach revolutionizes the robotics industry, enabling robots to adapt and learn from real-world scenarios continuously.
+
+## Challenges Faced by Developers
+
+Integrating cloud services with robots has traditionally been a daunting task for developers due to various challenges:
+
+- **Hardware Diversity:** Robots and sensors come in various Protocols and Drivers, making hardware integration complex and time-consuming.
+
+- **Robot Operating System (ROS) Compatibility:** ROS versions and standards may differ across platforms, causing compatibility issues.
+
+- **Cloud Service Integration:** Integrating cloud services often requires deep knowledge of specific APIs and complex configurations.
+
+- **Across Component Integration:** To achieve complete application development, we require a common API and research platform for sharing code, data, and models across services, control, algorithms, and data processing modules. However, despite its long history and extensive capabilities, `ROS` can be challenging for new users without the necessary expertise or time to fully understand the software stack.
+
+## Concepts
+
+Conceptual overviews provide relatively high-level, general background information about key aspects of `RoboSDK`.
+
+`RoboSDK` is a middleware on top of the robot operating system (ROS). It provides a consistent set of hardware-independent mid-level APIs to control different robots. These are the concepts that will help you get started understanding the basics of `RoboSDK`.
+
+- **ROS**: The Robot Operating System (ROS) is a set of software libraries and tools that help you build robot applications. From drivers to state-of-the-art algorithms, and with powerful developer tools, ROS has what you need for your next robotics project. Representative work includes: [ROS 1](https://wiki.ros.org/), [ROS 2](http://docs.ros.org/), and [OpenHarmony](https://www.openharmony.cn/).
+
+- **RoboArtisan**: `RoboArtisan` is a series of cloud-native robotics solutions that aims to simplify and democratize the research of sophisticated robotics scenes. Representative work includes: `RoboOMS`, `RoboSS`, `RoboAI`.
+
+- **RoboOMS**: The Robot Operation Management Service (RoboOMS) is a cloud-native robotics solution built on [KubeEdge](https://github.com/kubeedge/kubeedge). It provides a foundation for managing robot-cloud-edge communication, facilitating multi-robot collaboration, deploying applications, and conducting operations.
+
+- **RoboSS**: The Robot Simulation Service (RoboSS) is a cloud-native robotics solution built on [O3DE](https://github.com/o3de/o3de). It provides a simulation framework for cloud-native scenarios, allowing users to simulate robot scenarios, generate data, train skills, and experiment with digital twins using open-source simulators.
+
+- **RoboAI**: The Robot Artificial Intelligence Service (RoboAI) is a cloud-native robotics solution for building and deploying AI solutions. Representative work includes: [sedna](https://github.com/kubeedge/sedna).
\ No newline at end of file
diff --git a/docs/source/proposals/project_design.md b/docs/source/proposals/project_design.md
new file mode 100644
index 0000000..5326d43
--- /dev/null
+++ b/docs/source/proposals/project_design.md
@@ -0,0 +1,123 @@
+# RoboSDK Project Design
+
+## Architecture Overview
+
+`RoboSDK` is designed as a cutting-edge, cloud-native robotics application development ecosystem that simplifies the creation of complex robot applications. The architecture revolves around three core pillars: hardware abstraction, cloud service integration, and cross-platform support for various robot operating systems.
+
+
+
+### Hardware Abstraction Layer
+
+`RoboSDK`'s hardware abstraction layer serves as a bridge between developers and diverse robot hardware. It provides a standardized interface for accessing and controlling various sensors and actuators, regardless of the underlying hardware. This abstraction simplifies hardware integration, allowing developers to focus on the higher-level aspects of their applications without worrying about hardware-specific intricacies.
+
+By abstracting hardware interactions, `RoboSDK` promotes modularity and reusability, making it easier to create robot applications that are hardware agnostic. Whether you are working with different robots or upgrading hardware components, `RoboSDK`'s hardware abstraction layer ensures smooth integration and minimizes development effort.
+
+`RoboSDK` instantiating robot with a simple YAML file, developers can easily control the robot's actions through the imperative programming, following provide a simple example for understanding, you can study from `robosdk::core::robot` in depth.
+
+- Step 1: Create a robot instance with a YAML file.
+
+```yaml
+ # robot.yaml
+ name: "demo" # robot name
+ environment: # robot operating system
+ backend: "ros1"
+ requirement: # dependency python package
+ - rospy
+ - rostopic
+ - roslib
+ sensors: # robot sensors
+ camera:
+ - name: "cam1"
+ config: "simplecamera" # reference to the camera configuration named `simplecamera`
+ rgb:
+ target: "/usb_cam_1/image_raw"
+ actual_hz: 10
+ origin_hz: 30
+ is_compressed: false
+ info:
+ target: "/usb_cam_1/camera_info"
+ control: # robot control
+ - motion:
+ name: "ros_cmd_vel"
+ config: "cmd_vel"
+```
+
+- Step 2: Instantiating the Robot
+
+```python
+ # demo.py
+ from robosdk.core.robot import Robot
+
+ robot = Robot(name="demo", config="robot")
+ robot.connect() # initialize the robot by connecting to the sensors and actuators
+```
+
+- Step 3: Control the Robot
+
+```python
+ # demo.py
+
+ robot.motion.go_forward() # move the robot forward
+
+ rgb, timer = robot.camera.get_rgb() # get the rgb image from the primary camera
+```
+
+
+### Cloud Service Integration
+
+The framework offers built-in interfaces for cloud service providers, allowing developers to easily tap into cloud resources and deploy sophisticated algorithms. This integration unlocks the potential of data-intensive tasks, such as advanced data analysis, machine learning, and simulations, without overloading the robot's onboard resources.
+
+`RoboSDK` support the usual cloud-native functionalities by providing seamless integration with `RoboArtisan`'s existing cloud services, including `RoboOMS` (Robot Operation Management Service) and `RoboSS` (Robot Simulation Service), also support cloud-based `object storage` and `real-time audio and video`. This middleware-based approach empowers developers to efficiently utilize these cloud resources and access them through the `RoboSDK`.
+
+More details by visiting `robosdk::cloud_robotics`.
+
+
+### Cross-Platform Support
+
+`RoboSDK` is designed to support different robot operating systems, such as ROS 1, ROS 2, and openHarmony, fostering a collaborative and inclusive robotics community. By providing compatibility across various platforms, developers can work on their preferred robotic environments without worrying about compatibility issues.
+
+More details by visiting `robosdk::backend`.
+
+
+## Modular Development Workflow
+
+`RoboSDK` encourages a modular development workflow, allowing developers to focus on specific functionalities or capabilities. Each module within `RoboSDK` can be developed independently, promoting collaboration and enabling developers to contribute expertise in their areas of interest.
+
+The framework's modular approach also simplifies testing and debugging, making it easier to maintain and update individual components. This modularity enhances the overall stability and flexibility of `RoboSDK`, promoting the growth of the open-source robotics community.
+
+A sample is provided below, more details by visiting `robosdk::common::class_factory`.
+
+**For Navigation Algorithm Developers**
+
+```python
+ # demo.py
+ from robosdk.common.class_factory import ClassFactory
+ from robosdk.common.class_factory import ClassType
+
+
+ @ClassFactory.register(ClassType.NAVIGATION, alias="my_navigation")
+ class MyAlgorithm:
+ def __init__(self, config: str):
+ pass
+
+ def planning(self, step=0) -> PoseSeq:
+ pass
+
+```
+
+**For Navigation Algorithm Users**
+
+```python
+ # demo.py
+ alg_cls = ClassFactory.get_cls(
+ ClassType.NAVIGATION, "my_navigation"
+ )
+
+ navigation = alg_cls(config=alg_cfg)
+ pose_seqs = navigation.planning()
+
+ for inx, point in enumerate(pose_seqs):
+ robot.motion.go_to(point)
+```
+
+
diff --git a/docs/source/proposals/references.md b/docs/source/proposals/references.md
new file mode 100644
index 0000000..280b6e1
--- /dev/null
+++ b/docs/source/proposals/references.md
@@ -0,0 +1,9 @@
+# References
+
+## Release Notes
+
+- TBA
+
+## Meetup and Conference
+
+- TBA
\ No newline at end of file
diff --git a/docs/source/proposals/research/AStar path planning algorithm/README.md b/docs/source/proposals/research/AStar path planning algorithm/README.md
new file mode 100644
index 0000000..01781b4
--- /dev/null
+++ b/docs/source/proposals/research/AStar path planning algorithm/README.md
@@ -0,0 +1,21 @@
+# AStar Path Planning Algorithm Support in RoboSDK
+
+This research explores the integration of the AStar path planning algorithm into RoboSDK. It investigates how the AStar algorithm can be leveraged to provide efficient and optimal path planning for robots in complex environments. The research proposal discusses the algorithm's implementation, performance analysis, and its potential impact on cloud-native robotics applications.
+
+## Introduction
+
+The A* algorithm is a popular path planning algorithm widely used in robotics and artificial intelligence applications. Its ability to find the shortest path in a graph efficiently has made it a valuable tool for navigation and planning tasks in various domains. This research proposal aims to investigate the implementation and performance of the A* algorithm in the context of cloud-native robotics applications. By integrating the A* algorithm into the RoboSDK framework, we aim to assess its impact on robot navigation and explore its potential benefits in cloud-based robotics scenarios.
+
+
+
+## Objectives
+
+The primary objectives of this research proposal are as follows:
+
+1. Implement the A* algorithm in the RoboSDK framework to enable efficient path planning for robots.
+2. Analyze the performance of the A* algorithm in terms of computational complexity, memory usage, and time efficiency.
+3. Evaluate the A* algorithm's effectiveness in real-world robot navigation scenarios, considering different environments and obstacle configurations.
+4. Investigate the scalability of the A* algorithm when applied to large-scale robotic systems in a cloud-native environment.
+5. Explore the potential benefits of using the A* algorithm in cloud-native robotics applications, including reduced latency, enhanced navigation capabilities, and improved resource utilization.
+
+
diff --git a/docs/source/proposals/research/AStar path planning algorithm/animation.gif b/docs/source/proposals/research/AStar path planning algorithm/animation.gif
new file mode 100644
index 0000000..0cad36c
Binary files /dev/null and b/docs/source/proposals/research/AStar path planning algorithm/animation.gif differ
diff --git a/docs/source/proposals/research/README.md b/docs/source/proposals/research/README.md
new file mode 100644
index 0000000..4428101
--- /dev/null
+++ b/docs/source/proposals/research/README.md
@@ -0,0 +1,3 @@
+# Research in RoboSDK
+
+This directory contains valuable research efforts that contribute to the development and advancement of RoboSDK. Please note that the content within this directory is focused on research findings, concepts, and ideas and does not include specific implementation code. Additionally, the inclusion of research here does not guarantee immediate integration into the main RoboSDK codebase, and there are no fixed timelines or roadmaps for implementation.
\ No newline at end of file
diff --git a/docs/source/proposals/roadmap.md b/docs/source/proposals/roadmap.md
new file mode 100644
index 0000000..f40fcfa
--- /dev/null
+++ b/docs/source/proposals/roadmap.md
@@ -0,0 +1,16 @@
+# Roadmap
+
+This document defines a high level roadmap for RoboSDK development.
+
+The [milestones defined in GitHub](https://github.com/kubeedge/robosdk/milestones) represent the most up-to-date plans.
+
+## 2023 Roadmap
+
+- [x] **Enhanced Hardware Abstraction:** expand its hardware abstraction layer to support an even broader range of robot hardware.
+- [x] **ROS 1 Support**
+- [ ] **RoboArtisan Service Integration**
+- [x] **Improved User Interface and Documentation**
+- [x] **Real-World Use Case Demonstrations**
+- [ ] **Performance Optimization**
+- [x] **Security and Privacy Features**
+
diff --git a/docs/source/proposals/value_description.md b/docs/source/proposals/value_description.md
new file mode 100644
index 0000000..cc6020e
--- /dev/null
+++ b/docs/source/proposals/value_description.md
@@ -0,0 +1,37 @@
+# Value of RoboSDK: Empowering Cloud Computing, Robotics Industry, and Developers
+
+`RoboSDK` brings immense value to the cloud computing, robotics industry, and developers of all levels of expertise. Let's explore the key aspects that make `RoboSDK` a game-changer in the world of cloud-native robotics.
+
+## 1. Advancing Cloud Computing in Robotics
+
+### Cloud-Native Capabilities
+
+`RoboSDK` embraces cloud-native principles, enabling developers to leverage the full potential of cloud computing in robotics. By seamlessly integrating with cloud services, `RoboSDK` empowers robots to offload computation, access remote data, and tap into AI, Simmulation capabilities, revolutionizing the way robots perceive, reason, and interact with the environment.
+
+### Scalability and Resource Flexibility
+
+With `RoboSDK`'s cloud integration, robots gain access to virtually limitless computing power and storage resources. This scalability enables robotics applications to process large volumes of data and handle complex tasks efficiently. Moreover, developers can seamlessly scale their robot fleets to meet evolving demands in various industries.
+
+## 2. Transforming the Robotics Industry
+
+### Democratizing Robotics
+
+`RoboSDK`'s hardware abstraction layer and support for multiple robot operating systems democratize robotics. This lowers the barriers of entry for developers, making it easier for them to venture into the world of robotics without being constrained by specific hardware or proprietary software. As a result, more developers from diverse backgrounds can contribute innovative applications to the robotics industry.
+
+### Driving Innovation and Collaboration
+
+By adopting `RoboSDK`'s open-source approach, the robotics community can foster collaboration and knowledge-sharing. Developers worldwide can participate in the evolution of `RoboSDK`, contributing their expertise and collectively pushing the boundaries of cloud-native robotics. This collaborative effort accelerates the pace of innovation in the robotics industry.
+
+## 3. Enabling Developers of All Levels
+
+### Simplifying Complexities with Middleware
+
+`RoboSDK`'s middleware-based architecture simplifies the complexities of cloud service integration, robot hardware management, and communication protocols. Developers, regardless of their expertise level, can work more efficiently and focus on implementing high-level robot behaviors, application logic, and innovative algorithms without getting bogged down in low-level details.
+
+### Supporting Various Programming Languages
+
+With support for popular programming languages, including Python, C++(TODO), and more, `RoboSDK` accommodates developers with different language preferences and skillsets. Whether they are experienced in robotics or new to the field, developers can leverage their existing knowledge and programming languages to create powerful robot applications.
+
+## Conclusion
+
+`RoboSDK` brings exceptional value to the cloud computing, robotics industry, and developers worldwide. By promoting cloud-native principles, democratizing robotics, and empowering developers with user-friendly interfaces, `RoboSDK` propels the adoption of cloud-native robotics and fosters a vibrant ecosystem of innovative robot applications. As we embrace `RoboSDK`, we embark on a journey of transforming industries, driving cutting-edge research, and creating a future where cloud-native robots play an integral role in enhancing our lives and society as a whole.
\ No newline at end of file
diff --git a/robosdk/backend/ros1.py b/robosdk/backend/ros1.py
index f3cd3f3..ea14607 100644
--- a/robosdk/backend/ros1.py
+++ b/robosdk/backend/ros1.py
@@ -296,7 +296,7 @@ def _convert_from_ros_type(cls, field_type, field_value,
elif cls._is_ros_binary_type(field_type):
if binary_array_as_bytes:
field_value = cls._convert_from_ros_binary(field_value)
- elif type(field_value) == str:
+ elif isinstance(field_value, str):
field_value = [ord(v) for v in field_value]
else:
field_value = list(field_value)
diff --git a/robosdk/backend/ros2.py b/robosdk/backend/ros2.py
index 7d1bb8a..7eabd35 100644
--- a/robosdk/backend/ros2.py
+++ b/robosdk/backend/ros2.py
@@ -206,7 +206,7 @@ def _convert_from_ros_type(cls, field_type, field_value,
elif cls._is_ros_binary_type(field_type):
if binary_array_as_bytes:
field_value = cls._convert_from_ros_binary(field_value)
- elif type(field_value) == str:
+ elif isinstance(field_value, str):
field_value = [ord(v) for v in field_value]
else:
field_value = list(field_value)
@@ -261,7 +261,7 @@ def _convert_from_ros_array(cls, field_type, field_value,
if cls._is_ros_binary_type(field_type):
if binary_array_as_bytes:
field_value = cls._convert_from_ros_binary(field_value)
- elif type(field_value) == str:
+ elif isinstance(field_value, str):
field_value = [ord(v) for v in field_value]
else:
field_value = list(field_value)
diff --git a/robosdk/cloud_robotics/roboartisan/__init__.py b/robosdk/cloud_robotics/roboartisan/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/robosdk/cloud_robotics/roboartisan/base.py b/robosdk/cloud_robotics/roboartisan/base.py
new file mode 100644
index 0000000..23a7c4f
--- /dev/null
+++ b/robosdk/cloud_robotics/roboartisan/base.py
@@ -0,0 +1,236 @@
+# Copyright 2021 The KubeEdge Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import asyncio
+from datetime import datetime
+from datetime import timedelta
+from typing import List
+
+import aiohttp
+from robosdk.common.config import BaseConfig
+from robosdk.common.constant import RoboArtisan
+from robosdk.common.constant import RoboArtisanCloudAPI
+from robosdk.common.exceptions import CloudError
+from robosdk.common.logger import logging
+
+
+class CloudAPIProxy:
+ _ENDPOINT_NAME = "IAM_ENDPOINT"
+ _DOMAIN_NAME = "IAM_DOMAIN"
+ __timeout__ = 10
+ __update_token_period__ = 60
+
+ def __init__(
+ self,
+ service_name: RoboArtisan,
+ token: str = "",
+ project_id: str = "",
+ region: str = "default",
+ resource: str = "HuaweiCloud",
+ ):
+ self.logger = logging.bind(
+ instance=f"roboartisan_{service_name.name}", system=True
+ )
+ self.config = BaseConfig
+ self.cloud = RoboArtisanCloudAPI[resource]
+
+ self.service_name = service_name
+ self._token = token.strip()
+ self._project_id = project_id.strip()
+ self.__session__ = aiohttp.ClientSession(
+ headers={"Content-Type": "application/json"},
+ timeout=aiohttp.ClientTimeout(total=self.__timeout__),
+ connector=aiohttp.TCPConnector(verify_ssl=False),
+ )
+ self._region = region.strip()
+ self._should_exit = False
+
+ async def run(self):
+ raise NotImplementedError
+
+ def update_token(self, token: str = "", project_id: str = ""):
+ raise NotImplementedError
+
+ async def close(self):
+ await self.__session__.close()
+ self._should_exit = True
+
+ @property
+ def server_uri(self) -> str:
+ server_uri = self.cloud.get(self.service_name, "").strip()
+ region = self.config.get(self._DOMAIN_NAME, self._region).strip()
+ if not server_uri:
+ server_uri = self.config.get(self._ENDPOINT_NAME, "").strip()
+
+ return server_uri.format(region=region, project_id=self._project_id)
+
+ def __str__(self):
+ return self.service_name.value
+
+
+class CloudAuthProxy(CloudAPIProxy):
+
+ def __init__(self):
+ self.__token__ = None
+ self.__project_id__ = None
+ self.__token_expires__ = None
+ self.__token_lock__ = asyncio.Lock()
+ self._all_registry_event: List[CloudAPIProxy] = []
+ super(CloudAuthProxy, self).__init__(RoboArtisan.base)
+
+ def register_event(self, event: CloudAPIProxy):
+ self._all_registry_event.append(event)
+
+ def update_event_token(self):
+ for event in self._all_registry_event:
+ self.logger.debug(f"Update event token: {event}")
+ event.update_token(
+ token=self.__token__,
+ project_id=self.__project_id__
+ )
+
+ def update_token(self, token: str = "", project_id: str = ""):
+ """ not recommend to use this method, use _update_token instead """
+ if token:
+ self.__token__ = token
+ self.__token_expires__ = datetime.utcnow() + timedelta(
+ seconds=self.__update_token_period__)
+
+ if project_id:
+ self.__project_id__ = project_id
+
+ @property
+ def token(self):
+ return self.__token__
+
+ @property
+ def project_id(self):
+ return self.__project_id__
+
+ async def run(self):
+ while 1:
+ if self._should_exit:
+ break
+ async with self.__token_lock__:
+ check = await self._update_token()
+ if check or (not self.project_id):
+ self.__project_id__ = await self.get_project_id(
+ token=self.token
+ )
+ check = True
+ if check:
+ self.update_event_token()
+ await asyncio.sleep(self.__update_token_period__)
+
+ async def _update_token(self):
+ if (
+ self.__token__ and self.__token_expires__ and
+ datetime.utcnow() < self.__token_expires__
+ ):
+ return False
+ iam_server = self.server_uri
+ region = self.config.get(self._DOMAIN_NAME, "cn-south-1").strip()
+
+ name = self.config.get("username", "").strip()
+ password = self.config.get("password", "").strip()
+ domain = self.config.get("domain", "").strip()
+ self.logger.debug(f"Update token by {iam_server} - {name} @ {domain}")
+ if not (name and password):
+ raise CloudError("username or password not set", 401)
+
+ try:
+ self.__token__, self.__token_expires__ = await self.get_token(
+ name=name,
+ password=password,
+ domain=domain,
+ project_id=region
+ )
+
+ except Exception as e:
+ self.logger.error(f"Update token failed: {e}")
+ return True
+
+ async def get_token(
+ self, name, password, domain, project_id
+ ):
+ """ auth with username/password """
+ data = {
+ "auth": {
+ "identity": {
+ "methods": ["password"],
+ "password": {
+ "user": {
+ "name": name,
+ "password": password,
+ "domain": {
+ "name": domain
+ }
+ }
+ }
+ },
+ "scope": {
+ "project": {
+ "name": project_id,
+ }
+ }
+ }
+ }
+ _url = f"{self.server_uri}/auth/tokens"
+ resp = await self.__session__.post(
+ _url, json=data
+ )
+ if resp.status != 201:
+ _text = await resp.text()
+ self.logger.debug(f"Call {_url} fail: {data} => {_text}")
+ raise CloudError(f"auth failed, status code: {resp.status}")
+ token = resp.headers.get("X-Subject-Token")
+ token_detail = await resp.json()
+ token_expires_at = datetime.strptime(
+ token_detail['token']['expires_at'],
+ "%Y-%m-%dT%H:%M:%S.%fZ"
+ )
+ return token, token_expires_at
+
+ async def get_project_id(self, token: str = ""):
+ """ get project id from huawei cloud api """
+ if not token:
+ return
+ iam_server = self.server_uri
+ region = self.config.get(self._DOMAIN_NAME, "cn-south-1").strip()
+ _url = f"{iam_server}/projects"
+ self.logger.debug(f"Get project id by {_url} - {region}")
+ _headers = {
+ "Content-Type": "application/json;charset=utf8",
+ "X-Auth-Token": token
+ }
+ data = {
+ "enabled": "true",
+ "name": region
+ }
+ resp = await self.__session__.get(
+ _url,
+ params=data,
+ headers=_headers
+ )
+ if resp.status != 200:
+ _text = await resp.text()
+ self.logger.debug(f"Call {_url} fail: {data} => {_text}")
+ raise CloudError(
+ f"auth failed, status code: {resp.status}", resp.status)
+ res = await resp.json()
+ projects = res.get("projects", [])
+ self.logger.debug(f"Get project id by {_url} - {region} - {projects}")
+ if len(projects):
+ return projects[0].get("id")
+ return
diff --git a/robosdk/cloud_robotics/roboartisan/oms.py b/robosdk/cloud_robotics/roboartisan/oms.py
new file mode 100644
index 0000000..e4c27bd
--- /dev/null
+++ b/robosdk/cloud_robotics/roboartisan/oms.py
@@ -0,0 +1,417 @@
+# Copyright 2021 The KubeEdge Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import asyncio
+from typing import Dict
+from typing import List
+
+from robosdk.cloud_robotics.roboartisan.base import CloudAPIProxy
+from robosdk.common.constant import RoboArtisan
+from robosdk.common.exceptions import CloudError
+from robosdk.utils.util import genearteMD5
+
+
+class RoboOMS(CloudAPIProxy):
+ _page_size = 100
+ __update_period__ = 60
+ _ext_header = {
+ "Content-Type": "application/json;charset=utf8",
+ "X-Auth-Token": ""
+ }
+
+ def __init__(self):
+ super().__init__(RoboArtisan.robooms)
+ self._robot_data: List = []
+ self._deployment_data: List = []
+
+ self._robot_data_lock = asyncio.Lock()
+ self._app_data_lock = asyncio.Lock()
+ self._deployment_data_lock = asyncio.Lock()
+ self._all_properties_map = {}
+
+ def update_token(self, token: str = "", project_id: str = ""):
+ if token:
+ self._token = token.strip()
+ self._ext_header["X-Auth-Token"] = self._token
+ if project_id:
+ self._project_id = project_id.strip()
+
+ async def run(self):
+ while 1:
+ if self._should_exit:
+ break
+ if self._token and self._project_id:
+ try:
+ async with self._deployment_data_lock:
+ self._deployment_data = await self.get_app_deployment()
+ async with self._robot_data_lock:
+ self._robot_data = await self.get_robots()
+ except Exception as e:
+ self.logger.error(f"Update oms data failed: {e}")
+ await asyncio.sleep(self.__update_period__)
+ await asyncio.sleep(1)
+
+ @property
+ def robots(self):
+ return self._robot_data
+
+ @property
+ def num_robots(self):
+ return len(self._robot_data)
+
+ @property
+ def deployments(self):
+ return {d["id"]: d for d in self._deployment_data if "id" in d}
+
+ async def get_robot_properties(
+ self,
+ robot_id: str = "",
+ robot_type: str = ""
+ ) -> Dict:
+ """ get robot properties """
+ if not robot_type:
+ robot = await self.get_robot(robot_id)
+ robot_type = robot.get("type", "")
+ if robot_type in self._all_properties_map:
+ return self._all_properties_map[robot_type]
+ return {}
+
+ async def get_robots(self, offset: int = 0) -> List:
+ """ get all robot """
+ url = f"{self.server_uri}/roboinstances"
+ data = {
+ "limit": int(self._page_size),
+ "offset": int(offset),
+ "sort_key": "created_at",
+ "sort_dir": "desc"
+ }
+ resp = await self.__session__.get(
+ url,
+ params=data,
+ headers=self._ext_header
+ )
+ if resp.status != 200:
+ _text = await resp.text()
+ self.logger.debug(f"Call {url} fail: {data} => {_text}")
+ raise CloudError("get oms instance failed", resp.status)
+ res = await resp.json()
+ all_robot = res.get("roboinstances", [])
+ count = res.get("count", 0)
+
+ for robot in all_robot:
+ properties = await self.get_robot_properties(
+ robot_id=robot.get("id", ""),
+ robot_type=robot.get("type", "")
+ )
+ if "properties" not in robot:
+ robot["properties"] = {}
+ robot["properties"].update(properties)
+ if count > offset + self._page_size:
+ all_robot.extend(
+ await self.get_robots(offset + self._page_size)
+ )
+ return all_robot
+
+ async def get_robot(self, robot_id: str) -> Dict:
+ """ get robot by id """
+ url = f"{self.server_uri}/roboinstances/{robot_id}"
+ resp = await self.__session__.get(
+ url,
+ headers=self._ext_header
+ )
+ if resp.status != 200:
+ _text = await resp.text()
+ self.logger.debug(f"Call {url} fail: => {_text}")
+ raise CloudError("list robot failed", resp.status)
+
+ return await resp.json()
+
+ async def get_apps(self, name: str = "", offset: int = 0) -> List:
+ """ get all app """
+ url = f"{self.server_uri}/roboapps"
+ data = {
+ "name": name,
+ "limit": int(self._page_size),
+ "offset": int(offset),
+ "sort_key": "created_at",
+ "sort_dir": "desc"
+ }
+ resp = await self.__session__.get(
+ url,
+ params=data,
+ headers=self._ext_header
+ )
+ if resp.status != 200:
+ _text = await resp.text()
+ self.logger.debug(f"Call {url} fail: {data} => {_text}")
+ raise CloudError("get oms instance failed", resp.status)
+
+ res = await resp.json()
+ all_app = res.get("roboapps", [])
+ count = res.get("page", {}).get("count", 0)
+ if count > offset + self._page_size:
+ all_app.extend(
+ await self.get_apps(
+ name=name,
+ offset=offset + self._page_size
+ )
+ )
+ return all_app
+
+ async def get_app(self, app_id: str) -> Dict:
+ """ get app by id """
+ url = f"{self.server_uri}/roboapps/{app_id}"
+ resp = await self.__session__.get(
+ url,
+ headers=self._ext_header
+ )
+ if resp.status != 200:
+ _text = await resp.text()
+ self.logger.debug(f"Call {url} fail: => {_text}")
+ raise CloudError("get app failed", resp.status)
+
+ return await resp.json()
+
+ async def create_app(
+ self, name: str,
+ package_url: str,
+ package_type: str = "image",
+ package_arch: str = "arm64",
+ ros_version: str = "ros1_melodic"
+ ) -> str:
+ """ create app """
+ url = f"{self.server_uri}/roboapps"
+
+ for app in await self.get_apps(name):
+ if app.get("name") == name:
+ if app.get("package_url") == package_url:
+ return app.get("id")
+ await self.delete_app(app.get("id"))
+
+ data = {
+ "name": name,
+ "package_arch": package_arch,
+ "package_url": package_url,
+ "package_type": package_type,
+ "robo_suite": {
+ "ros_version": ros_version
+ },
+ "tags": {}
+ }
+
+ resp = await self.__session__.post(
+ url,
+ json=data,
+ headers=self._ext_header
+ )
+ if resp.status != 201:
+ _text = await resp.text()
+ self.logger.debug(f"Call {url} fail: {data} => {_text}")
+ raise CloudError("create app failed", resp.status)
+
+ res = await resp.json()
+ return res.get("id")
+
+ async def delete_app(self, app_id: str):
+ """ delete app """
+ url = f"{self.server_uri}/roboapps/{app_id}"
+ try:
+ await self.__session__.delete(
+ url,
+ headers=self._ext_header
+ )
+ except: # noqa
+ self.logger.error("delete app failed")
+
+ async def get_app_versions(self, app_id: str) -> List:
+ """ get app versions """
+ url = f"{self.server_uri}/roboapps/{app_id}/versions"
+ resp = await self.__session__.get(
+ url,
+ headers=self._ext_header
+ )
+ if resp.status != 200:
+ _text = await resp.text()
+ self.logger.debug(f"Call {url} fail: => {_text}")
+ raise CloudError("get app versions failed", resp.status)
+
+ res = await resp.json()
+ all_versions = res.get("roboapps", [])
+ return all_versions
+
+ async def create_app_version(
+ self, app_id: str,
+ release_type: str = "release",
+ release_version: str = "latest",
+ ) -> str:
+ """ create app version """
+ exits_version = await self.get_app_versions(app_id)
+ for app_data in exits_version:
+ version = app_data.get("release_version", "")
+ _type = app_data.get("release_type", "")
+ if version != release_version:
+ continue
+ if _type == release_type:
+ return version
+ await self.delete_app_version(app_id, version)
+
+ url = f"{self.server_uri}/roboapps/{app_id}/versions"
+ data = {
+ "release_type": release_type,
+ "release_version": release_version
+ }
+
+ resp = await self.__session__.post(
+ url,
+ json=data,
+ headers=self._ext_header
+ )
+ if resp.status != 201:
+ _text = await resp.text()
+ self.logger.debug(f"Call {url} fail: {data} => {_text}")
+ raise CloudError("create app version failed", resp.status)
+
+ return release_version
+
+ async def delete_app_version(self, app_id: str, version: str):
+ """ delete app version """
+ url = f"{self.server_uri}/roboapps/{app_id}/versions/{version}"
+ try:
+ await self.__session__.delete(
+ url,
+ headers=self._ext_header
+ )
+ except: # noqa
+ self.logger.error("delete app version failed")
+
+ async def get_app_deployment(self, offset: int = 0) -> List:
+ """ get app deployment """
+ url = f"{self.server_uri}/deployments"
+
+ resp = await self.__session__.get(
+ url,
+ headers=self._ext_header
+ )
+ if resp.status != 200:
+ _text = await resp.text()
+ self.logger.debug(f"Call {url} fail: => {_text}")
+ raise CloudError("get app deployment failed", resp.status)
+
+ res = await resp.json()
+ all_deployment = res.get("deployment_infos", [])
+ count = res.get("count", 0)
+ if count > offset + self._page_size:
+ all_deployment.extend(
+ await self.get_app_deployment(
+ offset=offset + self._page_size
+ )
+ )
+ return all_deployment
+
+ async def create_app_deployment(
+ self,
+ app_id: str,
+ robot_id: str,
+ version: str = "latest",
+ resources=None,
+ command: str = "",
+ run_args: List = None,
+ run_env: Dict = None,
+ volumes: List = None,
+ additional_properties: str = ""
+ ):
+ deploy_name = genearteMD5(f"{app_id}_{version}_{robot_id}")
+
+ for deployment in self._deployment_data:
+ if deployment.get("name", "") == deploy_name:
+ status = deployment.get("status", "")
+ self.logger.debug(
+ f"deployment {deploy_name} already exists, {status}"
+ )
+ await self.delete_app_deployment(deployment.get("id", ""))
+ launch_config = {
+ "host_network": True,
+ "privileged": False,
+ "additionalProperties": additional_properties,
+ }
+ if command:
+ launch_config["command"] = command
+ if volumes and isinstance(volumes, list):
+ launch_config["volumes"] = volumes
+ if run_env and isinstance(run_env, dict):
+ launch_config["envs"] = run_env
+ if run_args and isinstance(run_args, list):
+ launch_config["args"] = run_args
+ if resources and isinstance(resources, dict):
+ r_limits = resources.get("limits", {})
+ r_requests = resources.get("requests", {})
+ resources = {}
+ if r_limits:
+ resources["limits"] = r_limits
+ if r_requests:
+ resources["requests"] = r_requests
+ if resources:
+ launch_config["resources"] = resources
+
+ url = f"{self.server_uri}/deployments"
+
+ data = {
+ "name": deploy_name,
+ "robot_id": robot_id,
+ "description": "Deploy by teleop server, do not delete it",
+ "robot_app_config": {
+ "robot_app_id": app_id,
+ "version": version,
+ "launch_config": launch_config
+ }
+ }
+ resp = await self.__session__.post(
+ url,
+ json={"deployment": data},
+ headers=self._ext_header
+ )
+ if resp.status != 201:
+ _text = await resp.text()
+ self.logger.debug(f"Call {url} fail: {data} => {_text}")
+ raise CloudError("create app deployment failed", resp.status)
+ res = await resp.json()
+ return res.get("id", "")
+
+ async def delete_app_deployment(self, deployment_id: str):
+ """ delete app deployment """
+ url = f"{self.server_uri}/deployments/{deployment_id}"
+ try:
+ await self.__session__.delete(
+ url,
+ headers=self._ext_header
+ )
+ self._deployment_data = await self.get_app_deployment()
+ except: # noqa
+ self.logger.error("delete app deployment failed")
+
+ async def get_app_deployment_status(self, deployment_id: str):
+ """ get app deployment status """
+
+ url = f"{self.server_uri}/deployments/{deployment_id}"
+ resp = await self.__session__.get(
+ url,
+ headers=self._ext_header
+ )
+ if resp.status != 200:
+ _text = await resp.text()
+ self.logger.debug(f"Call {url} fail: => {_text}")
+ raise CloudError("get app deployment status failed", resp.status)
+ res = await resp.json()
+ self.logger.debug(f"get app deployment {deployment_id} status: {res}")
+ return res.get("status", "failure")
diff --git a/robosdk/common/constant.py b/robosdk/common/constant.py
index 60fb061..f4c14bb 100644
--- a/robosdk/common/constant.py
+++ b/robosdk/common/constant.py
@@ -134,6 +134,8 @@ class GaitType(Enum):
STAND = 1
HOLD = 2
TROT = 3
+ RUN = 4
+ SLIP = 5
FALL = 10
UPSTAIR = 11
UNKONWN = 99
@@ -144,4 +146,24 @@ class Motion(Enum):
ForceTimes = 10
+class RoboArtisan(Enum):
+ """meta services of RoboArtisan"""
+ base = "Base Service"
+ iam = "Identity and Access Management Service"
+ roboss = "Robot Simulation Service"
+ robooms = "Robot Operation and management Service"
+ robomap = "Robot Map Service"
+ roboskill = "Robot Skill Service"
+
+
+RoboArtisanCloudAPI = {
+ "HuaweiCloud": {
+ RoboArtisan.iam: "https://iam.{region}.myhuaweicloud.com/v3",
+ RoboArtisan.robooms: "https://oms.{region}.myhuaweicloud.com/v1",
+ RoboArtisan.roboss: "https://ss.{region}.myhuaweicloud.com/v1",
+ RoboArtisan.robomap: "https://map.{region}.myhuaweicloud.com/v1"
+ }
+}
+
+
DateTimeFormat = "%y%m%d%H:%M"
diff --git a/robosdk/common/fileops.py b/robosdk/common/fileops.py
index 128de54..9cac42c 100644
--- a/robosdk/common/fileops.py
+++ b/robosdk/common/fileops.py
@@ -53,6 +53,7 @@ class FileOps:
_AUTH_AK_NAME = BaseConfig.FILE_TRANS_AUTH_AK_NAME
_AUTH_SK_NAME = BaseConfig.FILE_TRANS_AUTH_SK_NAME
_DOMAIN_NAME = BaseConfig.FILE_TRANS_AUTH_DOMAIN
+ _SUB_DOMAIN = BaseConfig.FILE_TRANS_SUB_DOMAIN
_USE_PROXY = BaseConfig.FILE_TRANS_PROXY
@@ -357,10 +358,14 @@ def _create_http_client(cls):
client = AsyncRequest(proxies=use_proxy)
if _ak and _sk:
iam_server = ctx.get(cls._ENDPOINT_NAME, None)
- domain = ctx.get(cls._DOMAIN_NAME, None)
+ domain = ctx.get(cls._SUB_DOMAIN, None)
+ region = ctx.get(cls._DOMAIN_NAME, "cn-south-1").strip()
+ if not iam_server:
+ iam_server = f"https://iam.{region}.myhuaweicloud.com"
try:
client.auth_with_iam(
- _ak, _sk, server=iam_server, domain=domain)
+ _ak, _sk, server=iam_server,
+ domain=domain, project_id=region)
except: # noqa
pass
elif _ak:
diff --git a/robosdk/control/legged/ysc_control.py b/robosdk/control/legged/ysc_control.py
index e852439..fa04529 100644
--- a/robosdk/control/legged/ysc_control.py
+++ b/robosdk/control/legged/ysc_control.py
@@ -89,7 +89,10 @@ def dance(self):
self.sendSimpleCommand("DANCE")
def start_force_mode(self):
- self.sendSimpleCommand("START_FORCE_MODE")
+ self.sendSimple(3)
+
+ def start_auto_mode(self):
+ self.sendSimple(4)
def motion_start_stop(self):
self.sendSimpleCommand("MOTION_START_STOP")
@@ -121,12 +124,10 @@ def __init__(self, name: str = "ysc", config: Config = None):
super(DeepRoboticsControl, self).__init__(name=name, config=config)
self._GAIT_CODE = {
- 0: GaitType.LIEON,
- 1: GaitType.STAND,
- 2: GaitType.HOLD,
- 3: GaitType.TROT,
- 10: GaitType.FALL,
- 11: GaitType.UPSTAIR,
+ 0: GaitType.TROT,
+ 1: GaitType.UPSTAIR,
+ 2: GaitType.SLIP,
+ 3: GaitType.RUN,
}
self.msg_lock = threading.RLock()
self.curr_gait = GaitType.UNKONWN
@@ -162,6 +163,13 @@ def connect(self):
def get_curr_gait(self) -> GaitType:
return self.curr_gait
+ def force_control(self):
+ self.commander.start_force_mode()
+
+ def lie_down(self):
+ self.commander.motion_start_stop()
+ self.commander.stand_down_up()
+
def change_gait(self, gait: Union[str, GaitType]):
if isinstance(gait, str):
gait = getattr(GaitType, gait.upper())
diff --git a/robosdk/core/robot.py b/robosdk/core/robot.py
index 13bea7a..94c6d61 100644
--- a/robosdk/core/robot.py
+++ b/robosdk/core/robot.py
@@ -206,6 +206,7 @@ async def initial_control(self):
setattr(self, ctl.lower(),
MethodSuppress(logger=self.logger, method=ctl.lower()))
else:
+ driver.connect()
setattr(self, ctl.lower(), driver)
async def initial_skill(self):
diff --git a/robosdk/utils/request.py b/robosdk/utils/request.py
index 1bb1ed6..eccd0a3 100644
--- a/robosdk/utils/request.py
+++ b/robosdk/utils/request.py
@@ -78,33 +78,43 @@ def set_auth_token(self, token: str):
aiohttp.hdrs.AUTHORIZATION: token
})
- def auth_with_iam(self,
- ak: str, sk: str, server: str,
- domain: str = "Default"
- ):
- """
- auth with iam
- :param ak: access key
- :param sk: secret key
- :param server: iam server
- :param domain: domain name
- :return:
- """
- headers = {
- "Content-Type": "application/json",
- "X-Auth-User": ak,
- "X-Auth-Key": sk
+ def get_project_id(
+ self, server: str, token: str, region: str = "cn-south-1") -> str:
+ """ get project id from huawei cloud api """
+ if not (token and server):
+ return region
+ _headers = {
+ "Content-Type": "application/json;charset=utf8",
+ "X-Auth-Token": token
}
+ resp = self._loop.run_until_complete(
+ self._client.get(
+ url=server,
+ headers=_headers,
+ params={
+ "enabled": True,
+ "name": region
+ },
+ )
+ )
+ project = resp.json().get("projects", [])
+ if not project:
+ return region
+ return project[0]["id"]
- # generate post data
+ def auth_with_iam(
+ self, name, password, domain, server, project_id
+ ):
+ """ auth with username/password """
+ headers = {"Content-Type": "application/json;charset=utf8"}
data = {
"auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
- "name": ak,
- "password": sk,
+ "name": name,
+ "password": password,
"domain": {
"name": domain
}
@@ -112,13 +122,12 @@ def auth_with_iam(self,
}
},
"scope": {
- "domain": {
- "name": domain
+ "project": {
+ "name": project_id,
}
}
}
}
- # get auth token from iam server
resp = self._loop.run_until_complete(
self._client.post(
url=server,
@@ -138,7 +147,7 @@ def set_header(self, headers: Dict):
def set_cookies(self, cookies: Dict):
""" update cookies """
- self._client._cookie_jar.update_cookies(cookies)
+ self._client._cookie_jar.update_cookies(cookies) # noqa
async def __aenter__(self):
return self
@@ -196,7 +205,7 @@ def _get_proxy(self):
async def async_download(self, url: StrOrURL, dst_file: str,
method: str = "GET", **parameter):
- import aiofiles
+ import aiofiles # noqa
async with asyncio.Semaphore(1):
async with self._client.request(url=url, method=method,
diff --git a/robosdk/utils/util.py b/robosdk/utils/util.py
index c18906e..573a4ec 100644
--- a/robosdk/utils/util.py
+++ b/robosdk/utils/util.py
@@ -14,11 +14,14 @@
"""This script contains some common tools."""
import asyncio
+import hashlib
+import hmac
import os
import platform
import socket
import warnings
from copy import deepcopy
+from datetime import datetime
from functools import wraps
from inspect import getfullargspec
from typing import Callable
@@ -28,6 +31,31 @@
from robosdk.common.schema.pose import BasePose
+def HMAC256(key: str, msg: str) -> str:
+ """
+ HMAC256
+ """
+ return hmac.new(
+ bytes(key, 'utf-8'), bytes(msg, 'utf-8'),
+ hashlib.sha256
+ ).hexdigest()
+
+
+def genearteMD5(item) -> str:
+ hl = hashlib.md5()
+ hl.update(item.encode(encoding='utf-8'))
+ return hl.hexdigest()
+
+
+def gen_token(length: int = 4):
+ """
+ generate token
+ """
+ return str(
+ hashlib.sha256(str(datetime.now()).encode('utf-8')).hexdigest()
+ )[:length]
+
+
def cancel_on_exception(task):
"""
Cancel task on exception.