What’s new in AirSim-js 0.3 for TypeScript

ROS2JsGuy
4 min readAug 31, 2022

AirSim-js 0.3 was released yesterday (20220830) with several enhancements to simplify working with the AirSim TypeScript api. In this article we will introduce the key improvements of version 0.3.0.

If you are new to AirSim-js see this getting-started introduction.

New cameraLookAt() & plotArrow() methods

AirSim constructor arguments

Let’s start by looking at an improvement in the AirSim client constructor arguments. Now you have the following constructor overloads to choose from:

constructor(
vehicleClass: Constructor<T>,
port?: number);
constructor(
vehicleClass: Constructor<T>,
ipAddress?: string);
constructor(
vehicleClass: Constructor<T>,
port?: number,
ipAddress?: string);

Examples

new AirSim(Vehicle)
new AirSim(Car, '127.0.0.1')
new AirSim(Multirotor, 80)
new AirSim(Multirotor, 80, '127.0.0.1')

Integrated use of threejs-math classes

The Three.js 3D graphics library includes a rich set of linear algebra and geometry classes. Recently I forked and repackaged these math classes into the NPM threejs-math package, e.g., Vector3, Quaternion, Matrix4…, for stand-alone use in any Node.js package. In this release, I have fully replaced the AirSim server-side math types such as Vector3r with their much more capable threejs-math counterpart classes. You can identify native AirSim server-side types as they have the Raw prefix, e.g., RawVector3, RawCameraInfo… and are most prevalent on the Session api.

The new threejs-math classes used internally and exported by AirSim-js are:

Euler
MathUtils
Matrix
Matrix3
Matrix4
Plane
Quaternion
Ray
Vector
Vector2
Vector3

New types: Color, ColorName and CameraName

In previous releases, color was represented exclusively as an RGBA tuple, e.g., red =[1,0,0,1]. With the deeper integration of threejs-math, I’ve taken advantage of the three.js Color class and CSS color names to introduce a Color union type of either an RGBA tuple or a CSS color name.

type CSSColorName = 'aliceblue','antiquewhite','aqua','aquamarine','azure','beige','bisque','black','blanchedalmond','blue','blueviolet','brown','burlywood','cadetblue','chartreuse','chocolate','coral','cornflowerblue','cornsilk','crimson','cyan','darkblue','darkcyan','darkgoldenrod','darkgray','darkgreen','darkgrey','darkkhaki','darkmagenta','darkolivegreen','darkorange','darkorchid','darkred','darksalmon','darkseagreen','darkslateblue','darkslategray','darkslategrey','darkturquoise','darkviolet','deeppink','deepskyblue','dimgray','dimgrey','dodgerblue','firebrick','floralwhite','forestgreen','fuchsia','gainsboro','ghostwhite','gold','gold','goldenrod','gray','green','greenyellow','grey','honeydew','hotpink','indianred','indigo','ivory','khaki','lavender','lavenderblush','lawngreen','lemonchiffon','lightblue','lightcoral','lightcyan','lightgoldenrodyellow','lightgray','lightgreen','lightgrey','lightpink','lightsalmon','lightseagreen','lightskyblue','lightslategray','lightslategrey','lightsteelblue','lightyellow','lime','limegreen','linen','magenta','maroon','mediumaquamarine','mediumblue','mediumorchid','mediumpurple','mediumseagreen','mediumslateblue','mediumspringgreen','mediumturquoise','mediumvioletred','midnightblue','mintcream','mistyrose','moccasin','navajowhite','navy','oldlace','olive','olivedrab','orange','orangered','orchid','palegoldenrod','palegreen','paleturquoise','palevioletred','papayawhip','peachpuff','peru','pink','plum','powderblue','purple','rebeccapurple','red','rosybrown','royalblue','saddlebrown','salmon','sandybrown','seagreen','seashell','sienna','silver','skyblue','slateblue','slategray','slategrey','snow','springgreen','steelblue','tan','teal','thistle','tomato','turquoise','violet','wheat','white','whitesmoke','yellow','yellowgreen'type RGBA = [number, number, number, number];type Color = RGBA | CSSColorName;

The following table provides a color sample for each color name.

Color Names https://htmlcss.fandom.com/wiki/Color_Codes

I also merged the 2 forms for referencing a camera into a single CameraNameunion type.

type CameraName = string | 0 | 1 | 2 | 3 | 4;

New Vehicle cameraLookAt() method

The Vehicle class has a new cameraLookAt(target: Vector3) method that simplifies the aiming of any vehicle camera at a target location.

/**
* Rotate a camera to point towards a target position.
* @param cameraName - The name or id of the camera to move.
* @param target - The position to point camera towards.
* @param rearFacing - Set True when camera is mounting
* looking towards the rear of the vehicle, default = false.
* @returns A Promise<Pose> with the camera rotation..
*/
async cameraLookAt(
cameraName: CameraName,
target: Vector3,
isRearFacing = false
): Promise<Pose>

See the examples/lookat.ts program that demonstrates the use of this method to keep the orange ball in the Blocks environment centered in the front_center camera.

cameraLookAt(orangeBall)

Revised all AirSim.plotXXX() methods

In previous versions of AirSim-js the last 2 arguments of the AirSim plotXXX() methods were used to separately specify if the object being display was persistent or transient and for transient objects, how many seconds to display the object. This pattern was a little awkward. To improve usability the 2 arguments have been merged into a single union argument type.

Here’s the new argument list for the plotXXX() methods. Notice the durationOrPersistent union type argument which are now persistent by default.

/**
* Plots a list of arrows in World NED frame, defined
* from points_start[0] to points_end[0], points_start[1] to
* points_end[1], ... ,
* points_start[n-1] to points_end[n-1]
* @param pointsStart - Array of 3D start positions of arrow start
* positions, specified as Vector3 object
* @param pointsEnd - Array of 3D end positions of arrow start
* positions, specified as Vector3 objects
* @param color - Line color as RGBA tuple of values from 0.0 to 1.0 * or CSS color name. Default = 'red'.
* @param thickness - Thickness of line. Default = 5.0.
* @param arrowSize - Size of arrow head. Default = 2.0.
* @param durationOrPersistent - Duration (seconds) to display arrows
* or True to display indefinetly. Default = True.
* @returns A Promise<void> to await on.
*/
plotArrows(
pointsStart: Array<Vector3>,
pointsEnd: Array<Vector3>,
color: Color = 'red',
thickness = 5.0,
arrowSize = 2.0,
durationOrPersistent: number | true = true): Promise<void>

The following methods have been updated to use this durationOrPersistent pattern:

plotArrows()
plotLineList()
plotLineStrip()
plotPoints()
plotStrings()
plotTransforms()
plotTransformsWithNames()

The new lookat.ts example makes use of the `plotArrows()` method to display a red arrow parallel with the vehicle and a 2nd green arrow pointing to the center of the orange ball from the vehicle’s current location in the Blocks environment.

plotArrows() example

Wrapping Up

Thanks for checking out what’s new in AirSim-js 0.3.0. If you liked this article please give it a Thumbs Up and a share on twitter. You can reach me on Twitter at @ros2jsguy and find code that I’ve developed or working on at my GitHub account: https://github.com/ros2jsguy

Lastly, you can find additional AirSim-js examples in the AirSim-js GitHub repo. Until next time, Happy Coding!

--

--

ROS2JsGuy

“ROS 2 for JavaScript & TypeScript Developers” tutorials from a guy named Wayne