Cruisers Forum
 


Reply
 
Thread Tools Search this Thread Rate Thread Display Modes
Old 17-06-2020, 05:20   #1
Registered User
 
Antipole's Avatar

Join Date: Oct 2019
Boat: Alubat Ovni 395
Posts: 62
JavaScript Plugin

I have been hankering after a plugin that takes instructions in JavaScript. At home because of Covid-19 lockdown, I decided to learn C++ and about plugin programming... thank you Mike @Rasbats for help getting me going.

I now have a working prototype of my JavaScript plugin, which has a built-in JavaScript engine implementing ECMAScript E5.1 together with some features of E6 and E7. I introduce it here. This is rather a long post as there is a lot to say.

The plugin presents a console window comprising a script pane and a results pane and some buttons. You enter your JavaScript in the script pane (or load it from a file) and click on the Run button. The script is compiled into byte code and executed and any result is displayed. At its simplest, enter, say
Code:
(4+8)/3
and the result 4 is displayed. But you could also enter, say
Code:
function fib(n) {
    if (n == 0) { return 0; }
    if (n == 1) { return 1; }
    return fib(n-1) + fib(n-2);
}
function build(n) {
    var res = [];
    for (i = 0; i < n; i++) {
        res.push(fib(i));
    }
    return(res.join(' '));
}

print("Fibonacci says: ", build(20), “\n");
Which displays
Fibonacci says: 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
This illustrates how functions can be defined and called, including recursively. So we have a super calculator!

I have been developing interfaces (APIs) to OpenCPN and it is here that the fun starts. With my first, the following statement takes the supplied NMEA sentence, adds a checksum (replacing any existing one) and pushes it out over the OpenCPN connections
Code:
OCPNpushNMEA(“$OCRMB,A,0.000,L,,Yarmouth,5030.530,N,00120.030,W,
       15.386,82.924,0.000,5030.530,S,00120.030,E,V");
A challenge has been how to arrange for the processing of OpenCPN events. I have developed a way of specifying a function to handle a particular event, so we can write, for example
Code:
OCPNonNMEAsentence(handleNMEA);

function handleNMEA(result){
	if(result.OK){
	print(“Received: “, result.value, “\n”);
		}
	else print(“Bad checksum\n”);
	}
This listens out for the next NMEA sentence and displays it on receipt, if the checksum is OK.

Structures and methods

JavaScript supports the use of structures and methods. I have created a structure position, which allows me to write things like:
Code:
mypos = new position(50.234, 3.231);
// let’s change the longitude
mypos.value.longitude = -1.674;
Originally, I did not have the ‘value’ component, but I have added it to align with SignalK usage.

I have added some methods, such that
Code:
print(“My position is “, mypos.formatted(), ‘\n”);
// displays “My position is 50º 14.040’N 001º 40.440’W”
mypos.NMEA() returns the string 5014.04,N,140.44,W, which is the very odd way positions are represented in NMEA sentences.

NMEAdecode(string, n) decodes the nth position in an NMEA sentence. So
Code:
sentence = "$OCRMB,A,0.000,L,,UK-S:Y,5030.530,N,00120.030,W,15.386,82.924,
      0.000,5030.530,S,00120.030,E,V,A*69";
mypos.NMEAdecode(sentence,1);  // decodes NMEA sentence
print(mypos.formatted(), “\n");
// displays 50º 30.530’N 001º 20.030’W
A simple application

As an illustrative application, I note that @arnolddemaa was having problems capturing magnetic variation from HDG sentences and inserting into RMC sentences. Here is a solution which captures the variation from HDG sentences and inserts it into any RMC sentences that do not already have the variation. It changes the RMC sender identity so that the originals can be blocked by OpenCPN filtering. It works by splitting the sentence into an array of fields. Note how it ends by setting up to process the next NMEA sentence.
Code:
// insert magnetic variation into RMC sentence
var vardegs = "";	// where we will save the latest variation
var varEW = "";
OCPNonNMEAsentence(processNMEA);

function processNMEA(result){
	if (result.OK){
		sentence = result.value;
		switch (sentence.slice(3,6)){
			case “HDG:"  // capture variation
				splut = sentence.split(",");
				vardegs = splut[4];	varEW = splut[5];
				break;
			case "RMC":
				splut = sentence.split(",");
				if (splut[10] == "")  // if no variation already						{ 
					splut[10] = vardegs; splut[11] = varEW;
					splut[0] = “$JSRMC”;
					}
				result = splut.join(“,"); // put sentence together
				OCPNpushNMEA(result);
				break;
			}
		}
	OCPNonNMEAsentence(processNMEA);
	};
OpenCPN Messaging

I have implemented APIs to handle OpenCPN messages. Different messages can be directed to message-specific functions. For example:
Code:
//request route list
routeRequest = '{"mode": "Not track"}'   // JSON needed to get route
OCPNonMessageName(handleRL, “OCPN_ROUTELIST_RESPONSE”);
OCPNsendMessage("OCPN_ROUTELIST_REQUEST", routeRequest);

function handleRL(routeListJS){ //handle receipt of the route list
	routeList = JSON.parse(routeListJS);
	// notice how easy it is to parse the JSON into a structure
	// for illustration, here we extract the GUID of the first route
	firstGUID = routeList[0].GUID;
	}
Probing OpenCPN

I have found the plugin an excellent way of probing OpenCPN functionality, particularly as I can evolve the script in the light of what I get, iteratively. Wondering what a route list looks like? This will show you:
Code:
OCPNonMessageName(handleRL, “OCPN_ROUTELIST_RESPONSE”);
OCPNsendMessage("OCPN_ROUTELIST_REQUEST", JSON.stringify({"mode": "Not track”}));

function handleRL(routeListJS){  // handle route list response
	  print(routeListJS, “\n”);
	}
A more complex application

My own particular interest has been to develop a way of arranging that mobile devices running iNavx maintain an up-to-the-moment copy of an OpenCPN active route and shadow OpenCPN in a way that they will continue navigating the route were OpenCPN to fail. I have described that need in another post here. An advantage of iNavX is that it displays navigational information, including estimated times en-route, in a way optimised for iPad or small phone screens. The requirement is that
  1. the active route waypoints are sent out as a series of WPL sentences.
  2. These are associated into a route by a series of RTE sentences. Because of the 80 character limit, this takes a sequence of sentences using ’n of m’ notation. How many it takes depends on the length of the route and waypoint names.
  3. A BOD sentence is required to allow iNavX to navigate from the position where the next waypoint became active to the active waypoint.
  4. I have found that OpenCPN truncates the waypoint name in RMB sentences to 6 characters. Presumably, this is to allow for certain aged autopilots. This causes confusion if the active waypoint name is longer. I check RMB sentences for a truncated name and replace it with the full waypoint name.
The first step is to obtain the active route GUID. It turns out there is a bug in OpenCPN v5 whereby the returned GUID is actually the route name and not the GUID. This has been fixed in OpenCPN v5.1.605. So my script checks to see whether the route name was returned instead of the GUID and, if so, it has to fetch the full list of routes and look to see which is the active one. This extra work is avoided if the GUID is returned correctly.
I have a script that works as I require. It is too long to include in this post but it can be viewed here. This script includes many comments to aid understanding and I have left in, but commented out, some of the print statements used during its development. This shows key points in its evolution
.
Road map for future development

So far, I have only implemented the APIs needed to achieve my application above. I would like to hear of other possible applications so I can consider further APIs.
The plugin is not yet ready for alpha testing but I would be interested to work with others in a pre-alpha phase to develop ideas. This pre-alpha phase will be MacOS only as I use Xcode for debugging. I propose we use a Slack workspace I set up to liaise with Mike. If you would like to join in, please contact me by private message.
I anticipate developments will include:
  • Addition of further APIs as needed
  • Documentation and a user guide
  • Making the scripting window more programmer friendly. At present, it knows nothing of tabs, indents and braces. For other than the simplest script, I am using a JavaScript-aware editor (BBEdit in my case) and paste the scripts into the script window.
  • Better resilience. At present there is no protection against a script loop. while(1); hangs OpenCPN!
  • Implementing the JavaScript require() function, which is like a C++ #include to allow loading of pre-defined functions, objects, and methods.
  • Running without the console window visible
  • Tidier and more consistent error reporting, even when the console is hidden
  • ‘Canned’ scripts that start automatically
  • At present, if you want to do separate tasks, you would need to combine them into a single script. I have ideas about running multiple independent scripts.
  • I do not use SignalK but note its potential. I am interested in input from SignalK users to keep developments SignalK friendly.
Other suggestions?

Now to catch up on other things neglected over the past six weeks!
Antipole is offline   Reply With Quote
Old 19-07-2020, 07:14   #2
Registered User
 
Antipole's Avatar

Join Date: Oct 2019
Boat: Alubat Ovni 395
Posts: 62
JavaScript plugin release v0.1

My JavaScript plugin is now available as an alpha release v0.1.
The user guide is available here and an install package for MacOS can be downloaded from here.

I hope for feedback from users and am willing to implement further APIs to extend the interoperability with OpenCPN according to your interests.

I am Apple-based only, so am looking for volunteers to work with me on building the plugin for other platforms, especially Windows. As the present build uses Mac Xcode, someone with both Xcode and Windows would be ideal but we could probably manage if you are familiar with Cmake and the plugin development environment.

Development plan update
  • Addition of further APIs as needed
  • Documentation and a user guide ✔️
  • Making the scripting window more programmer friendly. ✔️
  • Better resilience. At present there is no protection against a script loop. while(1); hangs OpenCPN!
  • Implementing the JavaScript require() function, which is like a C++ #include to allow loading of pre-defined functions, objects, and methods. ✔️
  • Running without the console window visible ✔️
  • Tidier and more consistent error reporting, even when the console is hidden ✔️
  • ‘Canned’ scripts that start automatically
  • At present, if you want to do separate tasks, you would need to combine them into a single script. I have ideas about running multiple independent scripts.
  • I do not use SignalK but note its potential. I am interested in input from SignalK users to keep developments SignalK friendly.
Antipole is offline   Reply With Quote
Old 19-07-2020, 20:41   #3
Registered User
 
rgleason's Avatar

Join Date: Mar 2012
Location: Boston, MA
Boat: 1981 Bristol 32 Sloop
Posts: 15,067
Re: JavaScript Plugin

Antipole,

Would you like a Plugin page in the Development wiki?

It looks to me that your plugin may be well suited to use Frontend2 by Jon Gough which builds 13 environments that utilize the new Plugin Manager system, including MacOS.

I am currently working on converting Sean's plugins to this new system, but I can help and make suggestions for you to do that, if you like.


I don't think users / programmers realize how this might be used!
rgleason is offline   Reply With Quote
Old 20-07-2020, 15:13   #4
Registered User
 
Antipole's Avatar

Join Date: Oct 2019
Boat: Alubat Ovni 395
Posts: 62
Re: JavaScript Plugin

Rick...
Quote:
Would you like a Plugin page in the Development wiki?
Yes please

Quote:
It looks to me that your plugin may be well suited to use Frontend2 by Jon Gough which builds 13 environments that utilize the new Plugin Manager system, including MacOS.
Don't know about this but interested in giving it a go, especially if it simplifies making the plugin available on multiple platforms.

Quote:
I don't think users / programmers realize how this might be used!
So you see the potential? You seem to be the first to recognise what I am up to.

Quote:
I am currently working on converting Sean's plugins to this new system, but I can help and make suggestions for you to do that, if you like.
That would be great. I have a Slack workspace in which Mike R helped me get going. It works well. Will you join us? I could send an invite by PM.

Tony
Antipole is offline   Reply With Quote
Old 20-07-2020, 17:19   #5
Registered User
 
rgleason's Avatar

Join Date: Mar 2012
Location: Boston, MA
Boat: 1981 Bristol 32 Sloop
Posts: 15,067
Re: JavaScript Plugin

Tony,
I will make a page for you. Is the name Javascript_pi?

May I make you an editor? If so, please PM me your email and the wiki will send you access. I assume the user name would be Antipole.


That is great that Mike has helped on Slack. He also knows about frontend2 so he would be a big help too. I have a slack account and used it for signalK, but I don't use it often, I will have to dig that up for you.


We can start by adding your description below, then you can augment it.
rgleason is offline   Reply With Quote
Old 25-08-2020, 07:04   #6
Registered User
 
Antipole's Avatar

Join Date: Oct 2019
Boat: Alubat Ovni 395
Posts: 62
JavaScript Plugin v0.2 released

I have released v0.2 of this plugin and regard it as now beta status. New features include:
  • Added various APIs including those to access GUIDs, waypoints & routes
  • Script window greatly enhanced for writing JavaScript
  • User and technical guides developed
  • Error reporting regularised
  • Builds for Windows and Linux AMD
The user guide includes example scripts for creating or editing waypoints and routes.

Huge thanks to Mike Rossiter for getting it working on Windows and for the Windows and Linux builds

Available from the release page.

Bug reports and feature requests can be submitted here.
Antipole is offline   Reply With Quote
Old 25-08-2020, 10:32   #7
Registered User
 
AISEAG's Avatar

Join Date: May 2012
Location: Dahouet (Brittany)
Boat: BENETEAU
Posts: 474
Re: JavaScript Plugin v0.2 released

Quote:
Originally Posted by Antipole View Post
I have released v0.2 of this plugin and regard it as now beta status...
Thanks Antipode,

The next step could be the internalisation of this plugin (Crowdin).

Sorry I do not know the process

Serge
AISEAG is offline   Reply With Quote
Old 25-08-2020, 15:59   #8
Registered User
 
rgleason's Avatar

Join Date: Mar 2012
Location: Boston, MA
Boat: 1981 Bristol 32 Sloop
Posts: 15,067
Re: JavaScript Plugin

Antipole, I think you should ask Hakan via PM if he can set up the language files for your plugin. If you want to look at the po directory in some of the other plugins that mayhelp familiarize you.
rgleason is offline   Reply With Quote
Old 26-08-2020, 04:05   #9
Registered User
 
Antipole's Avatar

Join Date: Oct 2019
Boat: Alubat Ovni 395
Posts: 62
Re: JavaScript Plugin

I have consulted with Mike on this and understand the process by which the strings in the plugin could be translated.
As it is now, a user could write a script with output in their language of choice, i.e.
Code:
print("Die Ausgabe ist: ", ausgabe, "\n");
However, the JavaScript engine works in English only and so the script needs to be in English. Any error messages such as 'syntax error' will also be in English. The translation system would not address the API calls, nor the Javascript objects and methods. My guess is that, apart from script output as in the above example, less than 10% of output would be translated. So a working knowledge of English is essential and I think a few scattered translated words will confuse more than help.
I am sympathetic in principle, having lived in a non-English-speaking country. But I do not feel this is realistic for this particular plugin at least at the present time. I will keep the issue in mind.
Antipole is offline   Reply With Quote
Old 26-08-2020, 11:04   #10
Registered User
 
AISEAG's Avatar

Join Date: May 2012
Location: Dahouet (Brittany)
Boat: BENETEAU
Posts: 474
Re: JavaScript Plugin

Quote:
Originally Posted by Antipole View Post
I have consulted with Mike on this and understand the process by which the strings in the plugin could be translated.
....
@Antipole

Hello,

My suggestions was about all fixed terms on screen such as :

route calculation, Leg Distance, Tidal Current Data....

Thanks

Serge
AISEAG is offline   Reply With Quote
Old 26-08-2020, 11:12   #11
Registered User
 
Antipole's Avatar

Join Date: Oct 2019
Boat: Alubat Ovni 395
Posts: 62
Re: JavaScript Plugin

Quote:
Originally Posted by AISEAG View Post
@Antipole
Hello,
My suggestions was about all fixed terms on screen such as :
route calculation, Leg Distance, Tidal Current Data....
Thanks
Serge
Does not relate to this plugin Serge - maybe you have your threads crossed.
Antipole is offline   Reply With Quote
Old 26-08-2020, 11:35   #12
Registered User
 
AISEAG's Avatar

Join Date: May 2012
Location: Dahouet (Brittany)
Boat: BENETEAU
Posts: 474
Re: JavaScript Plugin

Quote:
Originally Posted by Antipole View Post
Does not relate to this plugin Serge - maybe you have your threads crossed.
Antipole,

You are right, I need to go on vacation again

On the screen, we can read word such as : Clear, Copy all, Run...

I do know that these are basics words but they can be scary for some people.

Serge
AISEAG is offline   Reply With Quote
Old 26-08-2020, 13:36   #13
Registered User
 
rgleason's Avatar

Join Date: Mar 2012
Location: Boston, MA
Boat: 1981 Bristol 32 Sloop
Posts: 15,067
Re: JavaScript Plugin

Serge, we all miss the point sometimes. Take heart.
rgleason is offline   Reply With Quote
Old 11-12-2020, 04:58   #14
Registered User
 
Antipole's Avatar

Join Date: Oct 2019
Boat: Alubat Ovni 395
Posts: 62
JavaScript Plugin updated to v0.3

New features include:
  • Additional APIs to OpenCPN include
    1. Get the vector to move from a start position to an end position
    2. Get the end position after moving by a vector from a start position
    3. Get Great Circle distance between two positions
    4. Get an array of the current AIS targets
  • Printing in colours or to the log file
  • Displaying an alert no longer holds up OpenCPN
  • Control over the script result and ability to exit at will
  • Support for creating dialogues and processing input from them
  • Protection against loops or scripts that get stuck - they will now timeout and not lock up OpenCPN
  • Hiding or showing the console window
  • Error handling has been regularised and there is no need to check for errors in many cases.
The user guide has been updated to cover the new features and includes more example scripts. The demonstration scripts include ‘Build race course’ which builds race routes from a selected subset of your waypoints and displays the course with directions.

The plugin is available from the release page, which includes builds for MacOS, Window and Linux. The release page also includes the user guide.

As before, huge thanks to Mike Rossiter for debugging on Windows and Linux and for those builds.

Bug reports and feature requests can be submitted here.
Antipole is offline   Reply With Quote
Old 11-12-2020, 05:13   #15
Registered User

Join Date: May 2011
Location: Lake Ont
Posts: 7,178
Re: JavaScript Plugin

This is very cool. I've seen this JS approach taken by some other open programs, and even some closed source projects. It lets more users experiment with custom features without the learning curve and complexity of modifying the main application.
Lake-Effect is online now   Reply With Quote
Reply

Tags
plug

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
JavaScript Plugin for OpenCPN? Antipole OpenCPN 1 21-02-2020 09:15
OpenCPN PlugIn Development bdbcat OpenCPN 161 04-09-2019 12:50
Plugin development... How to receive chart objects in my plugin? dmartinez OpenCPN 6 04-08-2017 00:56
Winlink Express problems with GRIB map and Javascript Slow Boat To... Marine Electronics 0 29-04-2017 14:23
Driving Revenue JavaScript S/V_Surya Forum Tech Support & Site Help 22 06-04-2011 12:26

Advertise Here


All times are GMT -7. The time now is 09:15.


Google+
Powered by vBulletin® Version 3.8.8 Beta 1
Copyright ©2000 - 2021, vBulletin Solutions, Inc.
Social Knowledge Networks
Powered by vBulletin® Version 3.8.8 Beta 1
Copyright ©2000 - 2021, vBulletin Solutions, Inc.

ShowCase vBulletin Plugins by Drive Thru Online, Inc.