# Matlab-Connector

You can find the Matlab Connector on Github. The idea of the connector is to facilitate the use of OKAPI’s API in Matlab. It provides general functions to initialize OKAPI in Matlab, send calculation requests and retrieve the results. It furthermore contains a simple error handling, so you are informed in case something goes wrong.

The whole connector is open source, and you are allowed to do anything you want with it. You can use it to send and retrieve any calculations possible with OKAPI. If you are integrating it into a larger software package, note that OKAPI’s API is currently being set-up and therefore undergoing rapid changes.

This tutorial is split in the following sections:

1. Getting started explains you how to retrieve the code from Github.
2. Using the connector gives a short introduction into the general layout and functionality of the connector. It also gives an overview of the included error handling.
3. Step-by-step example helps you to to login and process a request for the very first time. We suggest to go through the items once, and you should be ready to use the connector.

## Getting started

The code is released on Github. We recommend that you clone the repository from there, as it facilitates staying up-to-date with the API. To clone it, you have to have git installed on your machine. It is available for all operating systems. Generally, git is a command line tool, but for all operating systems also amazing GUIs exist. Furthermore, it is also integrated into Matlab directly.

To clone the repository from the command line, change into a directory of your choice and enter:

git clone https://github.com/OKAPIOrbits/OkapiMatlabConnector.git


The code including the complete repository will now be cloned to that folder and you can start using it. If you are integrating it into a larger software, remember to addpath path_to_connector to use it. If you want to get the newest version of the repository (for example because you are using a new version of the API), you can get the latest changes by executing

git pull

from the command line. Note that you have to be in the repository for this to work.

To use the Matlab solution, create a directory, in which you would like to clone the repository. Right click in the current folder window, and choose Source Control --> Manage Files. A window opens, make sure that you enter the options as shown below (note that you have to choose git as source control integration):

When you click Retrieve, the code is downloaded and included in your folder of choice. If you are integrating it into a larger software, remember to addpath path_to_connector to use it. To get the newest version of the Matlab connector, again right click in the current folder window and choose Source Control --> Pull. Git now downloads the latest version.

Note: Always make sure that you use the connector in combination with the version of OKAPI you are using. The master of the git-repository is always compatible with the latest release of OKAPI. For all other versions, you find tags of the connector with the same name as OKAPI release. In the future, OKAPI will include a check for the version of both the connector and the version running on the server, but the time, you have to perform this change manually.

## Using the connector

The connector is kept rather simple. All functions are contained in the folder src of the repository. You will find the following routines that folder:

1. OkapiInit performs the login and returns a token to authenticate yourself to the platform.
2. OkapiSendRequest posts requests to the OKAPI:Platform.
3. OkapiGetResult gets te results for the requests. Performs one call to the [API] and returns an error, if the computation was not yet finished.
4. OkapiWaitAndGetResult calls the API continuously over a defined time until the result is available.
5. OkapiSendRequestAndWaitForResult sends a request to the API and waits until the result is available or a maximum wait-time has passed.

For the beginning, the latter functions are more simple to use. For more sophisticated applications, it makes sense to use the asynchronous functions to not block your code while running computations on the platform. All functions return an error-struct, containing information on the status of the result. It is recommended to always check the information contained in that struct.

### General use

Generally, the use of the connector is always the same.

1. Every 24 hrs (or when re-starting Matlab), you have to get a new JWT token, which is retrieved using

OkapiLogin = OkapiInit(<url_to_okapi_as_string>,<your_username_as_string>,<your_password_as_string>);

As url use https://api.okapiorbits.com. The function returns a struct OkapiLogin, which contains all information you need to use OKAPI. You do not have to care about it anymore, it simply needs to be passed-on to the other routines.

2. Then, you have to set-up your request. OKAPI expects the requests as json, in Matlab you can use structs for this. Generally, you have to possibilities: if you have your requests as files, you can read them and convert them to a struct:

request_body = jsondecode(fileread(name_of_file_as_string));

Alternatively, you can create the structs in Matlab directly. An example for doing this is given below in the step-by-step example.

3. Now everything is set-up, so you can send the result. This is always done using

[request, error] = OkapiSendRequest(OkapiLogin, request_body, end_point_url_as_string);

A list of all available end_point_urls is given in the [API]-Documentation. The function call returns two items: a request, and an error struct. More details on the contents of the error struct are given below. The request only contains an id to retrieve your calculation results from the server. You won’t have to do anything with it, but pass it to the function to get the results.

4. Retrieve the results from the server. Note that generally the server needs a moment to process your request. You can tell Matlab to wait using sleep(seconds_to_sleep). Then, you can get the results using [result, error, end_point_url_as_string] = OkapiGetResult(OkapiLogin, requests); Again, the documentation of all available endpoints to retrieve the results are given in the [API]-Documentation. Note that most calculations return the results in different formats. Just choose the format you are interested in. You can also always get the results in all formats available. The function then returns the results of your calculation in the result-struct.

Instead of running steps 3 and 4 manually, you can also use the function OkapiSendRequestAndWaitForResult to send a request and wait until a result is available.

### Error handling

Until now we have ignored that all functions return an error object. As you probably do not want your program to crash every time something went wrong, the connector tries to catch the most probable errors that might occur. These errors are then returned to the calling program to decide how to handle them. Overall, the error-struct looks as follows:

error.status = STRING;
error.message = STRING;
error.web_status = integer;


The error.status contains the overall status of the process. It can contain the values 'NONE', 'REMARK', 'WARNING', and 'FATAL'. The first means that no information on the error state was returned by the server, so everything went fine. A REMARK states shows that the server returned some kind of information, which has no impact on the requested calculation. This might be a note that something will be changed in the API interface in a future release. WARNINGs indicate that something happened that might have an impact on the results, but still the results could be provided. In this case you should consult the message for further information and decide, if the warning is relevant for you or not. Last, FATAL means that the calculation could not be finished or the result is known to be wrong. In that case you should not use the returned result for any further calculations. Most often, FATAL states indicate that something went wrong during the communication with the server. The error.message gives you some further information on the state, for example if items in requests were missing. The error.web_response gives you information on the status of the web request. This is included, as a FATAL state for example can be due to web responses 404, 422, or 500. To identify the error, check out this value. Note that every time something went wrong with the server, you will have FATAL state. So that one should always be the one you handle.

There is one other very important case: it can happen that you request the results from the server before they have been fully processed. In that case, you will get a warning together with a web response 202 (expected). If this is the case, repeat requesting the results until you receive a 200 as http response.

### Step by step example

Enough with the theory, we know go through one example of using OKAPI step by step. Again, we will use the pass prediction for this. Note that the complete example is contained in the source repository, in the example folder. It will be updated with every release. Anyways, we recommend to go through this example yourself at least once.

At first, you need to tell Matlab were to find the connector functions. You can also work directly work in the src folder of the connector, but this will make it difficult over time to separate between your own and the connector functions. Add the path to the connector using addpath, in the case of the example contained in the repository it looks like this:

addpath ../src/


Second step is to perform the log-in. This is just a simple call of the function OkapiInit. The function returns an OkapiLogin, which you can use from now for all server communications.

OkapiLogin = OkapiInit('https://api.okapiorbits.com',your_username_as_string,your_password_as_string);


#### Preparing a request

Now, you have to set-up the request to send it to OKAPI. As explained above, there are different ways. The description of the request-formats is given in the Api-Documentation. To begin, you can just copy the request given here and save it to a file:

{
"orbit":{
"type": "tle.txt",
"content": "1 25544U 98067A   18218.76369510  .00001449  00000-0  29472-4 0  9993\n2 25544  51.6423 126.6422 0005481  33.3092  62.9075 15.53806849126382"
},
"ground_location": {
"type": "ground_loc.json",
"content": {
"altitude": 0.17012,
"longitude": 10.07,
"latitude": 50.2
}
},
"time_window": {
"type": "tw.json",
"content": {
"start": "2018-08-07T18:00:00.000Z",
"end": "2018-08-08T00:00:00.000Z"
}
}
}

You can then read this file directly to the correct fileformat using Matlab’s jsondecode and fileread functions:
RequestBody = jsondecode(fileread(name_of_file_as_astring));

Note that the TLE string contains a newline character. When reading from file it is translated correctly. But, in case you are setting up the struct yourself in Matlab, you need to use a different character. Here is an example how to set-up the a correct struct for the request. Note the newline in the TLE:
orbitContent = ['1 25544U 98067A   18218.76369510  .00001449  00000-0  29472-4 0  9993' newline '2 25544  51.6423 126.6422 0005481  33.3092  62.9075 15.53806849126382'];
orbit = struct('type', 'tle.txt', 'content', orbitContent);

groundLocationContent = struct('longitude',10.645,'latitude',52.3283,'altitude',0.048);
groundLocation = struct('type', 'ground_loc.json', 'content', groundLocationContent);

timeWindowContent = struct('start','2018-08-07T18:00:00.000Z','end','2018-08-07T20:00:00.000Z');
timeWindow = struct('type', 'tw.json', 'content', timeWindowContent);

RequestBody = struct('orbit', orbit, 'ground_location', groundLocation, 'time_window', timeWindow);


#### Sending a request and getting a result (in one step)

Now that the request is prepared, you can send it to the platform for computation. Easiest way is to use the function OkapiSendRequestAndWaitForResult: It sends the request to the server, waits for the computation to finish and returns the result. As inputs it requires the endpoints where to send the request, and where to get the result. In this example, we do a simple pass prediction with SGP4, so the call is

[result, OkapiError] = OkapiSendRequestAndWaitForResult(OkapiLogin, RequestBody, ...
'/predict-passes/sgp4/requests', '/predict-passes/sgp4/results/{request_id}/simple', 25);
if (strcmp(OkapiError.status, 'FATAL'))
% do something about fatal errors
error(OkapiError.message);
elseif (strcmp(OkapiError.status, 'WARNING'))
display(OkapiError.message);
elseif (strcmp(OkapiError.status, 'REMARK'))
display(OkapiError.message);
end

Note two things: First, the endpoint from which the result shall be retrieved, always contains the {request_id} placeholder. The integer in the very end tells the code for how long it shall try to retrieve the result. Once the computation is done, the result struct contains the result of your computation for further processing.

#### Sending a request

Alternatively, you can perform the single steps in between yourself. This helps writing more efficient code, as you can run computations asynchronously. Once the request is prepared, it can be send to OKAPI. There are different end points available to send pass prediction requests. We use the most basic predict-passes/sgp4/requests endpoint, which directly accepts TLE data:

 [result, OkapiError] = OkapiSendRequest(OkapiLogin, request, 'predict-passes/sgp4/requests');

This will send the request to the server, and return request and error structs. Before looking at the request, you should handle the error:
if (strcmp(OkapiError.status, 'FATAL'))
% do something about fatal errors
error(OkapiError.message);
elseif (strcmp(OkapiError.status, 'WARNING'))
display(OkapiError.message);
elseif (strcmp(OkapiError.status, 'REMARK'))
display(OkapiError.message);
end

In this example, the script is terminated in case a fatal error occurred. The error together with all other information available is printed to the screen. In case of warnings, the warning is shown but the script continues to run. You can of course decide on other actions for different types of errors.

#### Getting the result

Now the calculation is running on the server. Give it a short moment to perform the calculations. In Matlab, you can wait using pause(2), which should be enough for the pass prediction. To get the results, call:

[result, OkapiError] = OkapiGetResult(OkapiLogin, request, 'pass/predictions');

Remember to check for errors. In case the result has not been fully processed yet, you will get a 202 as response. In that case, try sending the request again. The result struct then contains your processed request, in the format as described in the [API]-Documentation. Especially if you are running calculations that take longer times to process (for example numerical propagations), consider getting the results in a while loop (with pauses in between), until the http response returns a 200. Do avoid DDOS attacks, you should also include a pause in that loop.

### Incomplete results

Usually, a result contains the complete result of your computation. In some cases, such as very long propagations and pass predictions, the result is incomplete. This is the case when your result contains more than 10000 entries (i.e. states or tracking entries). In that case, you will receive a warning.