|
1 | 1 | # NavAbilitySDK.py |
2 | 2 | Access NavAbility Cloud factor graph features from Python. |
3 | 3 |
|
| 4 | +Note that this SDK and the related API are still in development. Please let us know if you have any issues. |
| 5 | + |
4 | 6 | # Installation |
5 | 7 |
|
6 | | -Create a Python 3 virtual environment in the folder `venv`: |
| 8 | +We'll register the package shortly, but for the moment install the NavAbilitySDK directly from the repo: |
7 | 9 |
|
8 | 10 | ```bash |
9 | | -python3 -m venv venv |
| 11 | +pip install git+ssh://[email protected]/NavAbility/NavAbilitySDK.py.git |
10 | 12 | ``` |
11 | 13 |
|
12 | | -Activate the environment: |
| 14 | +# Notes and FAQ |
13 | 15 |
|
14 | | -```bash |
15 | | -source ./venv/bin/activate |
16 | | -``` |
| 16 | +- **Why is the SDK camel-cased?** True, Python code should be snake-cased. This was a design decision to align all the SDKS. All the functions and fields should look the same, so you can easily switch from one language to another without having to read documentation. This may change in the future as we grow the SDKs. |
| 17 | +- **Which user should I use?** The Guest user is open and free for everyone to use. We recommend testing with this user, because it doesn't require any authentication. Note though, that the data is cleared on a regular basis, and that everyone can see your test data (all Guest users are created equal), so don't put anything in there that that is sensitive. |
| 18 | +- **I have sensitive data, how do I create a user? ** Great question, the NavAbility services completely isolate data per user and you can create a user at any point. At the moment we create users on demand because the services are changing as we develop them, and we want to make sure we can let everyone know as they do. Send us an email at [[email protected]](mailto:[email protected]) and we'll create a user for you right away. |
| 19 | +- Otherwise for any questions, comments, or feedback please feel free to email us at [[email protected]](mailto:[email protected]) or write an issue on the repo. |
| 20 | +# Example |
17 | 21 |
|
18 | | -Install the NavAbilitySDK: |
| 22 | +This script will create variables and factors, list the graph, and solve the session for SLAM estimates. |
19 | 23 |
|
20 | | -```bash |
21 | | -pip install wheel |
22 | | -pip install git+ssh:// [email protected]/NavAbility/NavAbilitySDK.py.git |
23 | | -``` |
| 24 | +NOTE: You'll need numpy to run it. |
24 | 25 |
|
25 | | -# Example |
| 26 | +```python |
| 27 | +from uuid import uuid4 |
| 28 | +import numpy as np |
| 29 | +from navability.entities import ( |
| 30 | + Client, |
| 31 | + Factor, |
| 32 | + FactorData, |
| 33 | + FullNormal, |
| 34 | + NavAbilityHttpsClient, |
| 35 | + Pose2Pose2, |
| 36 | + PriorPose2, |
| 37 | + Variable, |
| 38 | + VariableType, |
| 39 | +) |
| 40 | +from navability.services import ( |
| 41 | + addFactor, |
| 42 | + addVariable, |
| 43 | + solveSession, |
| 44 | + ls, |
| 45 | + lsf, |
| 46 | + waitForCompletion, |
| 47 | + getVariable |
| 48 | +) |
26 | 49 |
|
27 | | -This script will create variables and factors, and demonstrate how to check the status one the way: |
| 50 | +navability_client = NavAbilityHttpsClient() |
| 51 | +client = Client("Guest", "MyUser", "Session_" + str(uuid4())[0:8]) |
28 | 52 |
|
29 | | -```python |
30 | | -import time |
31 | | -from navability.entities.Variable import Variable |
32 | | -from navability.entities.Factor import Factor, FactorPrior |
33 | | -from navability.entities.StatusMessage import StatusMessage |
34 | | -from navability.services.NavAbilityClient import NavAbilityClient |
35 | | -from pprint import pprint |
36 | | - |
37 | | -navi = NavAbilityClient() |
38 | | -result = navi.addVariable(Variable("x0", "Pose2")) |
39 | | -time.sleep(1) |
40 | | -statuses = navi.getStatusMessages(result['addVariable']) |
41 | | -pprint(statuses) |
42 | | -result = navi.addVariable(Variable("x1", "Pose2")) |
43 | | -time.sleep(1) |
44 | | -statuses = navi.getStatusMessages(result['addVariable']) |
45 | | -pprint(statuses) |
46 | | - |
47 | | -# Add a prior |
48 | | -result = navi.addFactor(FactorPrior("x0f1", "PriorPose2", ["x0"])) |
49 | | -time.sleep(1) |
50 | | -statuses = navi.getStatusMessages(result['addFactor']) |
51 | | -pprint(statuses) |
52 | | - |
53 | | -# Add a factor |
54 | | -result = navi.addFactor(Factor("x0x1f1", "Pose2Pose2", ["x0", "x1"])) |
55 | | -time.sleep(1) |
56 | | -statuses = navi.getStatusMessages(result['addFactor']) |
57 | | -pprint(statuses) |
58 | | - |
59 | | -# WIP |
60 | | -result = navi.solveSession() |
| 53 | +# Create variables x0, x1, and x2 |
| 54 | +variables = [ |
| 55 | + Variable("x0", VariableType.Pose2.value), |
| 56 | + Variable("x1", VariableType.Pose2.value), |
| 57 | + Variable("x2", VariableType.Pose2.value), |
| 58 | +] |
| 59 | + |
| 60 | +# Create factors between them |
| 61 | +factors = [ |
| 62 | + Factor( |
| 63 | + "x0f1", |
| 64 | + "PriorPose2", |
| 65 | + ["x0"], |
| 66 | + FactorData( |
| 67 | + fnc=PriorPose2( |
| 68 | + z=FullNormal(mean=np.zeros(3), covariance=np.diag([0.1, 0.1, 0.1])) |
| 69 | + ).dump() # This is a generator for a PriorPose2 |
| 70 | + ), |
| 71 | + ), |
| 72 | + Factor( |
| 73 | + "x0x1f1", |
| 74 | + "Pose2Pose2", |
| 75 | + ["x0", "x1"], |
| 76 | + FactorData( |
| 77 | + fnc=Pose2Pose2( |
| 78 | + z=FullNormal( |
| 79 | + mean=[1, 1, np.pi / 3], covariance=np.diag([0.1, 0.1, 0.1]) |
| 80 | + ) |
| 81 | + ).dump() # This is a generator for a PriorPose2 |
| 82 | + ), |
| 83 | + ), |
| 84 | + Factor( |
| 85 | + "x1x2f1", |
| 86 | + "Pose2Pose2", |
| 87 | + ["x1", "x2"], |
| 88 | + FactorData( |
| 89 | + fnc=Pose2Pose2( |
| 90 | + z=FullNormal( |
| 91 | + mean=[1, 1, np.pi / 3], covariance=np.diag([0.1, 0.1, 0.1]) |
| 92 | + ) |
| 93 | + ).dump() # This is a generator for a PriorPose2 |
| 94 | + ), |
| 95 | + ), |
| 96 | + ] |
| 97 | + |
| 98 | +# Get the result IDs so we can check on their completion |
| 99 | +result_ids = [addVariable(navability_client, client, v)["addVariable"] for v in variables] + [addFactor(navability_client, client, f)["addFactor"] for f in factors] |
| 100 | + |
| 101 | +# Wait for them to be inserted if they havent already |
| 102 | +waitForCompletion(navability_client, result_ids, maxSeconds=60) |
| 103 | + |
| 104 | +# Interrogate the graph |
| 105 | +# Get the variables |
| 106 | +ls(navability_client, client) |
| 107 | +# Get the factors |
| 108 | +lsf(navability_client, client) |
| 109 | +# There's some pretty neat functionality with searching, but we'll save that for more comprehensive tutorials |
| 110 | + |
| 111 | +# Request a SLAM multimodal solve and wait for the response |
| 112 | +# Note: Guest sessions solve a little slower than usual because they're using some small hardware we put down for community use. Feel free to reach out if you want faster solving. |
| 113 | +requestId = solveSession(navability_client, client)["solveSession"] |
| 114 | +waitForCompletion(navability_client, [requestId], maxSeconds=120) |
| 115 | + |
| 116 | +# Get the solves positions of the variables (these are stores in the PPEs structure) |
| 117 | +estimates = {v.label: getVariable(navability_client, client, v.label).ppes['default'].suggested for v in variables} |
61 | 118 | ``` |
0 commit comments