About This is Dexter Development Environment
version: ???
released: ???

DDE helps you create, debug, and send software to a Dexter robot. You can use any JavaScript augmented with DDE-specific functions to help find out about, and manipulate, a robot.
Videos on Dexter
Why Use DDE? Dexter has a limitless variety of capabilities. We couldn't think of them all let alone program them. And if we could, finding the right button for each program would be extremely difficult, besides overfilling screen real estate.

By providing a general purpose language that is broad enough to cover all the bases, yet detailed enough to specify the action details, users can specify the precise behavior they desire. We've extended JavaScript, the most common web page programming language, with dexter-specific functions like "move" and ways to get values from sensors (like cameras). This allows you to specify things like: If part X is in the workspace, then move it 10 millimeters to its left.

You need a general purpose language to customize that "10" with any computable number in a myriad of ways. We may want to create actions that depend on conditions that differ with the environment, time, or materials. Instead of move, we might want to rotate, or grasp, or drill, etc.
Won't a Text Editor Do? You could use any old text editor to write code. But you'd need to know:
  1. What capabilities are available?
  2. What do they actually do? (semantic details)
  3. How do I use them? (syntactic details)
  4. How do I run the code?
  5. How do I localize bugs?
  6. How do I understand and fix them?
  7. How do I store and re-run programs I've created?
  8. How do I change and extend existing code?
DDE helps you with all of the above.
Prerequisites You'll need a Dexter robot and a basic knowledge of JavaScript to make full use of DDE. DDE provides a lot of help for learning JavaScript directly and the Learning JavaScript section of this documentation gives you a number of very good on-line sources to smooth your path. Without a robot, you can still use DDE to simulate one.
First Install To get the latest DDE release, start the process by:
Updating to the latest DDE Follow the directions under First Install above. This will not change any files in your Documents/dde_apps folder.

Twist down the About row in the Doc pane to see the installed version number of DDE.
Launch DDE On Windows, the DDE application is installed in C:\Program Files\dexter_dev_env\dexter_dev_env.exe and on the desktop.
On Mac, Macintosh HD/Applications/dever_dev_env.app

Double click on the file to launch DDE.
The first time you launch, you will be told that you need to create a dde_apps folder under your Documents folder. The message you get should include the full path of this folder. For instance, on MacOS it will be "/Users/your_name/Documents/dde_apps/".
If there is a file Documents/dde_apps/dde_init.js, it will be loaded automatically. (If it does not exist in that folder, a new one will be made.) Thus you can put any code in that file that you want to be evaled at start-up, such as libraries you've written, etc.
Windows 10 Problem We suspect Microsoft's change to the default setting for a OneDrive configuration checkbox in a Windows 10 update in Feb or Mar 2018 causes DDE to not launch correctly. The underlying cause is that DDE can't find the right folder for its dde_init.js and/or dde_persistent.json files. This results in numerous problems like loading and saving files. Applications besides DDE have had similar problems.

If you are using Windows 10, we recommend:

  1. Right-click the OneDrive icon on the Windows Task Bar.
  2. In the dialog box that comes up, in its right-hand column, click "Settings"
  3. In the next dialog box that comes up, click the "Settings" tab.
  4. In the "Files on Demand" section, uncheck "Save space and download files as you use them"
If you have additional useful information about this issue, please tell us!
Configure DDE DDE requires that you create a folder under your Documents folder named dde_apps. If this does not exist when you launch DDE, you'll see a warning in the output pane.

DDE requires that you have a default robot named "dexter0". Usually the one that is automatically inserted into the file dde_apps/dde_init.js is fine. However, in that file you may need to modify the ip_address and port number of Dexter. The default ip_address is "" The port number is typically "50000".
Configure Dexter
Key Parts Dexter has 5 joints and 5 links between them. The two longest links are each about 32 centimeters long and made of square carbon fiber tubes. The tube closest to Dexter's base is LINK2.

Mounted on it is the motor controller printed circuit board, 17cm x 6 cm. Mounted on top of it is the processor board, 10cm x 6cm. Mounted on the bottom of the processor board is a metal housing containing an Ethernet socket for an RJ45 connector. The lower portion of the housing for the RJ45 contains a USB socket. To the left of the housing hanging over the bottom of the processor board is a micro USB socket. Underneath this housing on the motor controller board is a green-yellow LED. This is the "power" LED. It is fairly hidden, but you can see it between the boards if you look carefully.
Power Up When Dexter is off and disconnected from the power, you can move each joint manually with just a little resistence from Dexter. When transporting Dexter you should move the joints to fold it up into a compact configuration.

Moving a joint will cause a corresponding drive belt to move. You'll hear a "whirring" sound from the transmission. You should also see the power light to go on. Dexter's motors act as generators and will generate electricity which powers the power LED. Seeing the light go on when you move a joint is a diagnostic that the wiring is, at least partially, correct.

Dexter does not have an on-off switch. You just plug it into its power adapter and the wall to turn it on. The power adapter that comes with Dexter is a fairly common "power brick" or "wall wart" used on many PC laptops. It is about 3 meters long. The wall end is a 2 prong, unpolarized connector, common for USA appliances. Electrically, it accepts input of 100 to 240 volts, 50 to 60 Hz AC, which is supplied throughout the world. However, mechanical connections vary from country to country. Adapter plugs that accept the USA 2 prong plugs are commonly available.

The Dexter end of the power adapter is a male cylinder 5mm in outer diameter, common on older PC laptops. The Power Adapter consumes 1.5 Amps and outputs 3.15 Amps at 19 volts. If you lose it, many PC laptop power adapters will work.

Before turning on Dexter, move its joints so that its standing straight up. With the power board facing you, the final link should be horizontal pointing to the left. Dexter's power socket is connected by 2 short wires to Dexter's base. You turn on Dexter by plugging in the the power adapter to Dexter and the wall. If the wall has power, an LED on the power adapter will go on.

When Dexter is turned on, after about 8 seconds, it does a 5 second or so little "dance" moving each of its joints.

The processor board has 3 bright LEDs. The base of the motor controller board has 3 green-yellow LEDs on one side and 2 on the other. Each indicates that a joint has power.
Data Connection Ethernet Cable
Use an Ethernet cable (with RJ45 male connectors) to go between Dexter and your computer. Available at Staples, Home Depot, Best Buy, Amazon, etc. Ethernet cables come in different "Categories". Get "Cat 5e". The Ethernet socket on Dexter is on the bottom of the processor board with the socket facing down. Most modern laptop computers lack an Ethernet socket but there are USB 3.0 to Ethernet RJ45 adaptors for about $15 here. Get one that purports to work with your OS, as there are some incompatibilities. Beware that for some adaptors for some OS's you need to install a software driver, typically downloadable for free from the USB to Ethernet adaptor's website.

For connecting an Apple MacBook to Dexter, we recommend Apple USB Ethernet Adapter. However, Apple does a great job of changing their connectors every year or two so that your old peripherals won't work. For instance, on the 2018 MacBook Pro, the only connector they have is USB-C. USB-C has a lot of functionality, but the connector is physically different than previous USB connectors. Be careful when getting an Ethernet adaptor that it matches the socket on your computer.

The software setup for such direct-wire connectivity is a bit tricky. First, make sure your cable is plugged into and firmly seating in both your computer and Dexter.
On Windows 7:
  1. Go to Start/Control Panel
  2. Click on: "Network and Sharing Center"
  3. In the left column, click on "Change adapter settings".
  4. In the new dialog, click right on "Local Area Connection" and
  5. Choose "Properties".
  6. In the new dialog, in "Network" tab, click on "Internet Protocol Version 4" to select it.
  7. Click on the "Properties" button. This presents yet another dialog box.
  8. Select "Use the following IP address"
  9. Enter ip address:
  10. The Subnet mask should be:
    255 255 255 0
  11. Leave the "Default gateway blank.
  12. Click the OK button and close the remaining dialogs.
On MacOS:
First, newer new Macintoshes that don't have an Ethernet socket will need a "dongle" from USB (or Thunderbolt) to Ethernet socket. You can buy these at a Apple store or online (see above Apple URL).

For an older Mac with an Ethernet socket, or one you manage to get working with a dongle:
  1. Disconnect your WiFi (sorry, its necessary) by clicking on the "Radio waves" icon in the upper right of the screen. Choose "Turn WiFi Off".
  2. Select Apple Menu/System Preferences
  3. If your OS version is Sierra, a mostly useless dialog will come up. You have to click the left arrow in the upper left of this dialog to get the useful System Preferences with lots of choices.
  4. Click the "Network" icon to get another dialog box.
  5. Running down the left side of this dialog is an unlabeled column of all the possible connections. Apple cleverly made this column too narrow to be useful, so hover your mouse over each items to be able to read one in full. You're looking for a USB to Ethernet connection. Look for one with the phrase "Connected" under it. For the dongle we recommend above, it will be labeled "Apple USB Ethernet Adaptor"
  6. Clicking on the connection changes the inputs to the right.
    For the Configure IPV4 field, choose Manually
    Choosing Manually causes the inputs below it to change.
    For the IP Address field, enter:
    For the Subnet Mask field, type in
    For the Router field, leave it blank.
  7. Click the "Apply" button. If you are wired to Dexter, the left column entry for "Apple USB Eithernet Adaptor" there should now be a green dot.
We are working on making this easier.

Dexter is shipped with an ip_address of The Jobs menu item "Ping a Dexter" lets you test connectivity of a specific Dexter as well as find all the "host" Dexters that are connected at a "network" address. This is effectively an IP address scanner, useful when you don't know what ip addresses are connected.

You can also use a low level tool called "command prompt" or "terminal" to verify connectivity. Windows and Mac OS's do an excellent job at hiding these useful tools.
On Windows 7,
Start/All Programs/Accessories/Command Prompt.
On MacOS: try
Enter ping

If you have connectivity you should see something like the cryptic:
Reply from bytes=32 time 1ms
several times. Without connectivity you'll see something like:
Destination host unreachable or
Request timeout or
Host is down several times.

To stop the output of ping, type Cottrol_c.

Use Jobs menu/simulate submenu, and select false

You should now be able to move Dexter from DDE. For instance, choose Jobs menu/Run Insruction/NEUTRAL_ANGLES or, in case the robot is already at NEUTRAL_ANGLES, choose Jobs menu/Run Insruction/HOME_ANGLES, and Dexter should move.

Problems with data connectively can be do to an improper IP address of your Dexter, i.e. at some other address than It might also have to do with its "MAC" address (nothing to do with "Macintosh") not being correctly set. You can use an IP scanner to see what devices are connected to your computer, including a Dexter robot. There are many such apps available on the net. We suggest: If you have just one Dexter, use the correct IP address to redefine dexter0 in your dde_apps/init_dde.js file like so:
        new Dexter({name: "dexter0", ip_address: ""})
You can insert the definition of a Dexter in the Jobs menu/Run Instruction/Show Dialog.
Verify Joint Wiring To verify that all 5 joints are wired correctly:
  1. Verify that the Jumpers on processor board are configured like in this picture.
    processor board jumpers picture.
    This is a picture of the lower half of Dexter's processor board. The 3 jumpers that must be in the right position are the horizontal black rectangles on the lower left part of the board.
  2. Choose DDE's Jobs menu/Run Instruction/Show Dialog..."
  3. for J1 through J5, make each Joint's 30 degrees with the others at 0, and click on move_all_joints and observe that that joint should move by 30 degrees. The movement should make a low volume continuous whirring sound. If there are any abrupt noises, that can indicate a mechanical error in assembly.
Test Connectivity You should now be able to ping Dexter and have connectivity.
(See above on how to "ping".)
Ping doesn't find the host? Try reseating all the cables. Try power cycling Dexter and/or your computer.
If you are using an Ethernet cable, there are two LEDs on top of the RJ45 socket. When the amber one is lit, it shows connectivity. The green LED indicates data transfer.

Using DDE
On the Jobs menu/Simulate? submenu, choose "false". Now choose Jobs menu/Run Instruction/NEUTRAL_ANGLES, or other angles.

If the robot moves, you can control it from DDE! The next step is calibrating Dexter. Choose the menu item Jobs menu/Calibrate Dexter to start.

We recommend choosing ? in the upper right corner of the Doc pane to understand the Help System.
Dexter's File System Dexter's processor board runs Linux. Once you are connected to Dexter, you should be able to browse this file system using your computer's file navigation tools. Dexter's file system will show up as a separate "Volume" or "Device". On the Mac, in the Finder, you should see, in the left column, Localhost. Click on it. In a half minute or so, you should see in the right (main) pane of the finder a single folder share. This folder is on Dexter. Expand it to see several files on Dexter.

DDE can also access this share folder on Dexter. Use the File menu/Open to edit a file. You can save modified files on Dexter too.
Calibrate Dexter When
To obtain optimal precision, Dexter must be calibrated after it is built.

Environmental effects of heat, humidity, movement, and orientation towards gravity, all conspire to make minor changes that affect Dexter's accuracy. Calibrate optical sensors will most likely only need to be done once. If you received a fully assembled Dexter, this initial calibration has been done. If you are building a kit, you must calibrate it when the building is complete. Calibrate optical encoders needs to be done every time Dexter is turned on. If Dexter is having sporadic movement or is not smooth in FollowMe mode, try going through a full calibration.

Choose the Jobs menu item of "Calibrate Dexter..." to open a dialog aiding calibration.
Step 1
Select the robot to calibrate. If you have only one Dexter, the default of dexter0 will already be selected.
Step 2
Calibrate optical sensors by calibrating each of the five joints. When you click the start button for a joint, this begins a Job that draws thousands of points in the large white square plot area on the right of the dialog. If you don't see points drawn, you probably have your robot set to simulate i.e. new Dexter({simulate: true}) or have that simulate init param set to null which causes it to look at the Jobs menu/Simulate? radio buttons for a value, or there is a discontinuity in your wiring. If the robot has its simulate init parameter set to null (the default and the case for dexter0), choose Jobs menu/Simulate?/ of false.

For each Joint, you are tyring to get the drawn points to form a near-circle. Twist the two trim pots on the small printed circuit board (the "optical board" which is several centimeters per side) for the joint that you are calibrating, until the drawn points form a circle, or as near a circle as you can make. The desired circle fills the white plot area in the dialog, not smaller and not larger.

Joints 1, 4, and 5 also have two screws to adjust the position of the optical blocks. If you see the drawn points form the pattern of an elongated diagonal oval, that indicates that the positional screws need to be adjusted.

All adjustments can be made with the provided small screw driver.

As you adjust, the screen will become cluttered with now obsolete dots. Click the "Restart" button to clear the dots and start calibrating the selected Joint over again.

Allow the drawing of points to complete (several minutes). If the circle looks good, click the mouse in the center of the circle. This will draw a red point there. If you are not satisfied with the center you've chosen, click the mouse again at a new location.

Once you are satisfied with the circle center you've chosen, click the next joint's start button

When you've completed calibrating all five joints, click the "Save" button. This saves the center points for each joint in a file named "AdcCenters.txt" in Dexter's shared folder. (currently only working on a PC).
During calibration, if you get an alert error message:
"The direction of the eye ..." then it means one of two possible problems:
  1. The direction of the joint motion is reversed. Verify by moving the joint in question by adding degrees to its current position (use Jobs menu/Run Instruction/Show Dialog) and seeing if it moves in the direction indicated in these diagrams.

    If you find that the joint motion is reversed, the file on Dexter shared/AxisCal.txt needs to be edited to flip the sign of the 5 numbers,i.e. if they are positive, add a "-" in front of each number, if they are negataive, remove the "-".
  2. If joint moves in right direction. then the optical sensor wire polerity could be reversed. Check wiring.
Advanced Step 2
To save time or examing a specific joint angle range, use the 2 number widgets to confine joint angle motion to between the min and max degrees in the number widgets. Click the "Reset Ranges" button at the bottom of the dialog to initialize the min and max angles to their defaults for all joints.
You can also check the "looping" checkbox for a joint to have Dexter ossilate between the min and max set degrees.

Points are recorded as Dexter is running for a given joint. You can click the "eye" radio button to the right of a joint's start button to show its recorded points. The clear button at the bottom of the dialog erases the recorded points for the currently selected joint.
Step 3
Calibrate optical encoders
Caution! Clear area for large robot movements.
Calibrate the optical encoders by clicking the bottom button in the dialog. This will take about a minute. When the directions line in Step 2 says that calibration is complete, you can close this dialog by clicking the x in its upper right corner.
User Interface
Help System Web programmers spend an inordinate amount of time searching the web because of missing or incomplete documentation. DDE bends over backwards to provide the documentation you need to create jobs. There are quite a number of ways to get "just in time & place" help within DDE. We've tried to make them easy to discover, but in such a sophisticated environment, you might miss a few. So here's the list:
Editor Pane The Editor pane is a text editor. You can view and edit any text documents in it, but primarily you will be editing JavaScript that defines a job to make something with Dexter. DDE expects you to save such "apps" in your Documents/dde_apps/ folder.

The red dots on the left column of the editor indicate possible syntactic errors. Many of these are unnecessary or trivial formatting issues that will not affect running the code. If the code doesn't Eval, look at the red dots and their tooltips for clues.
Output Pane DDE prints information in the Output pane that will be useful in your current context. You can explicitly print in the output pane with a call to the JavaScript function out. Example:
out("hi world", "blue")
out accepts any valid HTML as its first argument. It will be rendered in the Output pane.
Start Job Button Clicking this button evals and starts the job that the cursor is in.

If the cursor is in a job's source code but not in the do_list, then the job source will be evaled, and the job started.

If the cursor is on an instruction in the do_list with no selection, the job will be evaled and started with the first instruction run being the one the cursor is on.

If there is a selection within the do_list, then the first instruction run will be the one that contains the start of the selection, and the last instruction run will be the one that contains the end of the selection. This works by setting the job's program_counter and ending_program_counter properties.

If you have selected the source code for one or more instructions (with comma's between them) and there is no new Job() wrapper around the instructions, then a Job wrapper will be automatically made behind the scenes, the job will be defined, and started.

Just before an instruction is run, it will be selected in the editor.
Documentation Pane The Documentation pane describes the core knowledge you'll need to command Dexter to make things. Admittedly we'll always fall short of this goal, but let us know if some crucial information is missing and we'll do our best to fill the void.

You can find out what version of DDE is running and the latest changes under the Release Notes section of the documentation. Details about programming Dexter are in the Reference Manual section.
Simulate Pane
The simulate pane shows a graphical simulation of Dexter with joint angles of the last heartbeat robot status returned. (By default, heartbeats happen every 100ms.)

Use the mouse in the Simulate pane to:
  • Rotate table: mouse-down then drag.
  • Zoom: shift-down then mouse-down then
    drag right to make bigger, drag left to make smaller
  • Pan: alt or option down, then mouse-down, then drag.

shows Dexter randomly flailing around, not correlated to a connected Dexter.

The menu in the Simulate pane header let's you browse several videos showing off Dexter's capabilities.
Stepping Instructions To understand a Job's behavior, its useful to step through each instruction. Checking the pause checkbox will cause running jobs to pause when they have completed their current instruction. Jobs started when the pause button is checked will pause right before the first user instruction on the do_list is run.

When a job is paused, clicking the button will cause it to execute the next instruction, print out useful information in the Output pane, and pause. If a job is paused, and you uncheck the pause checkbox, then click the button, the job will begin running normally.

debugger The instruction of Robot.debugger() in a do_list will cause the pause checkbox to be checked and the job to pause. A function that returns the result of Robot.debugger() or even an array that has an element of the result of Robot.debugger() will cause a pause.

You can insert this instruction using the Learn JS menu/Debugging etc/Robot.debugger().

Note that using Robot.debugger() is intentionally similar to using the JavaScript constant debugger. If you have the constant debugger in the body of a function that is a do_list item, or is called by a do_list item, it will cause a JavaScript breakpoint and you can step through that code using the Chrome dev tools. See Documentation top level section Debugging.
JavaScript DDE let's you control a Dexter robot with Javascript. You can execute all of JS. DDE extends JavaScript with a library of functions that control Dexter, allow access to Unix commands on Dexter's computer, Window system extensions, as well as ROS specific function calls allowing you to find out about and control Dexter.

In DDE, console.log sends its output to the (usually hidden) Chrome console. Use out (on the menu) to see output in the Output pane.
Learning JavaScript The quickest way to learn most of the JavaScript you'll need is from the Editor Pane's menu. Read menu item tooltips, choose an item to insert code, then click to eval all the code in the Editor. If there's a selection when you click , just the selected code will be evaluated. In fact, works on any selected text. Try it by: Choose menu items under in depth-first order for a consistent overview, and later you can choose exactly those items you need to insert a code snippet.
Warning Code in the editor that has not been evaled will have no effect.

A nice interactive tutorial is available at: https://www.codecademy.com/learn/javascript Beware that console.log prints to the normally hidden chrome console. DDE's out is easier to use.

If you want more prose, there are lots of JavaScript tutorials on the web. You will not need to know HTML, CSS or JQuery that are commonly taught in conjunction with JavaScript.

A very gentle intro to JavaScript. Ignore the parts that use the Underscore library.
A more formal (and long) tutorial.
JS for Programmers If you're already a competent programmer but don't know JS specifics, here's a few tips:
JavaScript is an untyped language. That means you don't declare types of variables, function parameters, or return values. So for instance,
C's       int foo = 32;
in JS is var foo = 32;
The type system is, um, weak. The object system is also in somewhat of disarray. Because of that there are many packages adding a more rational Object system, but they all differ, confusingly.

There's no compiler in JavaScript. There are no "includes" or "pre processors" or "macros". The code is run in an iterpreter inside a browser (every browser, actually). The major browsers also offer a debugging environment, though typically no Editor. DDE gives you an editor and a lot of other convenieces for developing code.

Whitespace characters are those characers that "take up space" but you can't otherwise see. This includes space, tab, newline and a few others. In Javascript, mostly its the case that 1 whitespace character is equivalent to any number of contiguous whitespace characters. Except that function calls need to be ended with either a semicolon or a newline, not just a space. For example:
Math.min(3, 4); Math.min(5, 6)
is legal, as is:
Math.min(3, 4)
Math.min(5, 6)

but not:
Math.min(3, 4)  Math.min(5, 6)

There is no Window System per se in JavaScript but it ties into HTML, CSS and the browser's Document Object Model. This is confusing since it requires several different syntaxes and ways-of-thinking. DDE simplifies this by providing the key window system facilites you'll need for commanding Dexter via the function show_window, the Human.enter_* instructions and a few other utilities. See the menu.

Javascript's functionality greatly expanded in 2016 with a new version who's name itself is confusing. You'll see EcmaScript 6, JavaScript 2015 and a few variants. Browsers vary as to how much of this they implement, but Chrome, the browser DDE uses, has nearly 100% of this new standard implemented as of June, 2016. DDE depends on these new features.

See in, this documentation, Installation/Keep Chrome up to date. JS 6 can run code from earlier versions of JS, but there's an awful lot of new functionality that isn't in most existing JS documentation.

Like all popular programming languages, JavaScript has its problems. But its unique in its "deployability". JS and DDE runs on Windows, Macs, Linux, and Chromebooks. Its new features are quite powerful, and DDE strives to make learning and using JS as simple as possible. Your new skills will serve you well in Web programming for billions of users.

Recommended JS Tutorials for the experienced programmer (both of which ignore the new JS 6 extensions):
JS re-introduction
more comprehensive
Eventually you will need to know the concepts of ROS (the Robot Operating System), though not the syntax of BASH, C++ and Python normally required to work with ROS.
Workflow DDE let's you execute arbitrary JavaScript that is entered into the Editor pane.
  1. The Editor pane's menus allow you to insert useful code snippets into the Editor pane.
  2. You can edit and extend the inserted code. Use any valid JavaScript.
  3. Click the button. The result of the last expression evaluated will appear in the Output pane.
  4. If there is a selection when the button is clicked, only the selected code will be executed.
  5. Triple click on a line to select it.
  6. Alt-click on a JS function call to select it.
Try this: type into the editor
2 + 3
Click and see 5 in the Output pane.
Persistent Data When you have defined a named function, set a global variable or a property reachable by a global variable, that data will remain in the JS environment until you relaunch DDE. This is even true if you bring a new file into the editor.

Overall this facilitates programming, but it does have some behavior that may be unexpected. Imagine you define
function foo(){return bar()} and
function bar(){return 'stuff'}
You call foo() => 'stuff'. Now you rename bar to baz like so: function baz(){return 'stuff'}and test baz() => 'stuff' as expected, as does calling foo() => 'stuff'. Now The call to foo will error because bar is no longer defined. When redefining function and global variables, its a good idea to save your code in file(s), relaunch DDE, and reload your code periodically, to check against such issues.
Working with Dexter
  1. In the output pane, enter any Unix BASH shell command in the shell type in and hit enter. It is run on Dexter's computer. Returned text will be printed below. The command you typed in will also be added to the Output pane's menu under "User Commands" should you want to execute it again.
  2. The Output pane's menu allows easy access to finding out about the ROS environment.
  3. If you click on underlined text in the Output pane, it will scroll to a relevent section of the Doc pane, or, in the case of core JavaScript, pop up a window of documentation.
UI Design Critera Criteria for Choosing Best UI Design Candidate: Such criteria, if complete, nearly always have "opposites" in them such that 1 design can't possibly do all best, though that is something to strive for. If all design criteria are met best by one design, you don't have to weight the criteria, which is always problematic.
Series A useful way to organize knowledge is to construct lists of similar-typed concepts. DDE calls such lists series. There are over 30 series in DDE, including numbers, dates, colors, functions for math, strings, arrays, etc. The most useful functions and data structures in DDE are in a series.

The menu allows you to insert into the editor, an example item from each series. When you click on a series item in the editor, help is given on that item in the Output pane. Using the Right and Left arrow keys, you can replace a selected series item with the next or previous item in its series. The Up and Down arrow buttons replace a selected series item with an item from another series. Effectively this uses the series of series.

An example of a series is boolean. Choose it from the menu. It inserts true. Now hit the right arrow key to see additional items in the series (false, null, etc.) The left arrow goes backwards through the series.

With any series item selected, hit the down arrow. If you're on a member of the boolean series, this will replace the selection with an item from the integer series. Press the up and down arrows to go to a new series.

Each time you go to a new item from series or click on one already in the editor, help on it will be displayed in the Output pane.
Jobs A job feeds the instructions in its do_list to a robot for making things. Most users of DDE will spend most of their time creating and running jobs.

The menu gives help on Jobs and Robots.
The menu contains numerous examples of defining Jobs and how to run them. Choose Insert example 1 and read the comments to understand Job syntax. See the Reference Manual on Job for the details of specifying a job.
Robots A robot is a machine capable of performing the instructions in its instruction set. The class hierarchy of DDE Robots is:
To get a robot to perform instructions, you create an instance of its class, giving it at least a name (and in the case of Dexter, an ip_address and a port number) then create an instance of Job and give it a robot property of the robot you created. The job should also have a do_list, which is the sequence of instructions to run on the robot. When the start method is called on a Job, it sends the items on its do_list to the associated robot, sequentially, one at a time.

From a software standpoint, a robot is its instruction set. The key difference between different kinds of Robots is the difference between their instruction sets. If a robot is sent an instruction not in its instruction set, it will error, because it doesn't know how to perform that kind of instruction.

Robot is the superclass of all robot classes. It contains instructions that can run on all robots. These are control instructions because they help manage the flow of instructions in a job. Examples include: Robot.stop to end a job immediately without processing the insructions after the stop instruction, and Robot.wait_until which pauses execution of the job's instructions until the calling of the given JS function returns true.

See submenu "robot" for details about robots as well as the Reference Manual section on Robots.
Drawing with DXF Dexter can draw the lines specified in a dxf file. To do that, Dexter needs to know a bunch of other information, most importantly the plane that it will be drawing on. Note that only line segments are currently supported. The DXF shapes of Circles, fillets, and polylines etc. are not.

To draw, you must define the plane of the drawing surface. A plane can be defined by specifying three points. We define each point using an array of 3 numbers, x, y, and z in meters for each point. You set these points in the 2nd argument to DXF.init_drawing as an array of three points or in other words, an array of three element where each element is an array of three numbers. By doing repeated calls to DXF.init_drawing (tweaking the points each iteration) and running a job to see where the robot moves, you can hone-in on good locations for these points.

The default input args assume that the plane that you are defining is approximately horizontal, in the x-y plane. If this is not the case, the plane_normal_guess arg can be changed to specify the approximate desired plane normal vector. This variable controls the orientation of the last joint while you are searching for the plane points but will not affect the drawing process.

The drawing process will calculate the direction (See Glossary on 'direction') based off of the the plane that was defined by the three points and move Dexter to be perpendicular to it.

If it is desired to have the robot point in the direction of the calculated plane during the point finding process, set the calc_plane_normal arg to true. This is not recommended until the points are dialed in due to large changes in normal direction.

The 3 points should form a right triangle. The vertices of this triangle will be the three points that define the plane. The order these points are chosen will not matter. If the "DXF_units" argument to DXF.init_drawing is undefined, ie not passed in, tben DXF_units will automatically be chosen.

Here's how. The legs of the right triangle (the non-hypotenuse sides) form an x and y axis for the drawing's coordinate system. The triangle leg that is in the clockwise direction from the other leg will always define the x-axis and counter-clockwise, the y-axis. With the origin being the point they share and the z-axis being perpendicular. This clockwise calculation is from the endeffector's point of view with assumption that if the robot can physically touch the point then it's last joint is on the front facing side of the plane. The rectangular bounding box is also formed by these three points. The two points on the x-axis leg of the triangle define the base line segment of the rectangle. While the third point determines the rectangle's height. Note that the angle between the x-axis and y-axis triangle legs can be between 45º and 180º apart for this to still work. Where the y-axis and rectangle height will be defined by the perpendicular from the x-axis to the third point. In other words it creates a perfect right triangle from the approximate one. This is important because the points that define the x-axis contribute to the orientation of the local coordinate system more than the y-axis point.

When DXF_units is undefined, the size of the drawing will be set such that the drawing will be the maximum size that it can be and still be contained within the bounding box. The "aspect ratio" of the drawing won't change to completely fill the bounding box. So usually the drawing will touch only 3 sides of the bounding box.

Drawing Details
  1. Attach drawing end effector such as a pen or laser to Dexter
  2. On a flat work surface within Dexter's reach, place a flat work piece (paper, cardboard etc.)
  3. Before turning Dexter on, orient all joints to
    [0, 0, 0, 0, 0] (straight up)
  4. Choose Jobs menu/DXF.init_drawing() to insert a call to init_drawing into the editor buffer.
  5. Edit the DXF_filepath argument to contain a string of the filepath of the dxf file you want to draw.
  6. Select the call and click .
    This defines a bunch of jobs that use the arguments to init_drawing.
  7. Start Job.Cal by clicking added to the Jobs bar by DXF.init_drawing. When it is complete ...
  8. Start Job.Point1 by clicking in the Jobs bar. Dexter will move to the first point defined in the three_points argument to init_drawing.
  9. If it is not where you want it, adjust the x, y and z of the first point.
  10. Now evaluate the call to init_drawing again. If the point is closer to where you want it, good, you're moving in the right direction. If not, adjust the x, y and z values to move in the correct direction.
  11. Keep tweaking x, y, and z until the first point is where you want it.
  12. Now follow this process for the other two points in the three_points argument, clicking and to move Dexter until you have the 3 points defining a right triangle on the drawing surface.
  13. Once the points are just about where you want them, set the calc_plane_normal argument to true to check the points using the calculated normal. This is the normal that will be used while drawing.
  14. Adjust the lift_height argument to init_drawing for the height above the drawing surface that the pen will go to when moving to start drawing a new line.
  15. Adjust the resolution, draw_speed and DXF_units in the remaining arguments to init_drawing. Select the call and click
  16. Start drawing by clicking on
DXF.init_drawing DXF.init_drawing defines a bunch of jobs to help set point locations and initialize the values used by jobs for laser cutting or drawing with a pen.

dxf_filepath This argument has several different formats for allowing the user to specify the lines to be drawn.
Other args Please see the below example.

    DXF_filepath: "choose_file",        //file_path to DXF
    three_points: [[0, .50, 0.1],    //Point1
                    [0, .35, 0.1],   //Point2
                    [.200, .35, 0.1] //Point3
                    ], //all numbers in meters
    plane_normal_guess: [0, 0, 1], //initial guess of plane normal. (usually [0, 0, 1], [+-1, 0, 0], or [0, -1, 0])
    calc_plane_normal: false, //if true then plane_normal_guess is ignored and plane_normal is determined by three points
    tool_height: 0.057000, //if in home position, vertical distance from the tool tip down to axis of rotation of J4
    tool_length: 0.140000, //if in home position, horizontal distance from the tool tip down to axis of rotation of J4
    DXF_units: undefined,  //units the DXF was drawn in, _mm, _in, _cm etc.
                           //undefined means the drawing will fit the bounding box
    draw_speed: .03,       //cartesian speed in (m/s)
    draw_res: 0.0005,      //resolution for max step size of interpolated straight line in meters
    lift_height: 0.01,     // height that the pen lifts between unconnected lines in meters
    tool_action: false,    ///enable tool actions (true or false)
    tool_action_on_function:  function(){
                                  return [make_ins("w", 64, 2),
    tool_action_off_function: function(){
                                  return [make_ins("w", 64, 0),
The tool_action_on function is called when drawing a line just after the "pen goes down" on the surface. For a laser the function would turn on the laser.

The tool_action_off function is called when drawing a line just before the "pen goes up" from the surface as it completes drawing a line. For a laser, the function would turn off the laser.
See also draw_dxf instruction
ezTeach EZ Teach is a tool to help you create jobs that move Dexter along a path of points. The points are recorded from you positioning Dexster either by hand, or by using a gamepad controller. The EZ Teach code is encapulated in 2 jobs.

User scenario:
ezCreate is a job that helps you create and save the points of the path that you want Dexter to follow.

User scenario:

ezRun is a job that helps you run the job that follows the points defined in ez_create.

User scenario:
Find Home Find Home is a tool that you use to help Dexter locate its true home position. It requires having a "dock" that Dexter parks in a known location.

Find Home is a part of Dexter Calibration. To use Find Home:
  1. Choose Jobs menu/Calibrate Dexter
  2. Select the Dexter you want to calibrate (default dexter0)
  3. If you have just built your Dexter from a kit, calibrate each of the 5 joint's optical sensors. Dexter's bought pre-built will have had this done at the factory.
  4. If you have never chosen the button , do so.
  5. Click the button. This will start the FindHome job and pop up the FindHome dialog box.
  6. With one hand grab Dexter's last link (so it wont fall), then in the FindHome dialog box, click the button
  7. Move Dexter into the parked position in the doc near the bottom of the robot.
  8. Let go of Dexter.
  9. Click the button
  10. Click the button
TestSuite For a video presentation of the Test System, please watch Reliability via Testing.

DDE has the capability to compose, run and report on Test Suites. DDE comes with several Test Suites and you can define more.

Each Test Suite has a name and an array of tests. A test is composed of an array of 1, 2, or 3 literal strings.
  1. A literal string of JavaScript code to evaluate that returns a value to be tested. If that string evals to an instance of a Job, then the rest of the test array is ignored, the job is started, and the running of the test suite is suspended until the job has finished. Then the test suite is resumed at the next instruction after the Job-defining test. Subsequent tests can now verify values in the finished job.
  2. The expected value of the above JavaScript code, also represented by a literal string of JavaScript.
  3. A literal string of a comment to aid in understanding the purpose or behavior of this test. If the comment starts with "known", then if the test does not pass, it will be reported on as an "known" failure. Other failures will be reported as "unknown". Often it is convenient to mark a test as "known" when you'd like to defer fixing it and just want to see the "unknown" failures.
Choose Insert Example to see a demonstation Test Suite.

You run a Test Suite by selecting it,holding down the Alt(option) key, and hitting the right arrow key or choosing the Editor pane's Test/naviation/Run & sel next item menu item. Use the Alt-down arrow key to select the next level down item such as a test or even a part of a test. In each case, the Alt-right arrow executes the item and selects the next item at that level. See the Test/Navigation menu for selecting different parts of a test suite.

To create a Test Suite, type in the JavaScript source of the suite's first test, select it, and choose Selection to test. This will wrap a Test Suite around the item and fill in the test's expected value with the result of evaluating the code you have selected. If you do that again for a second JavaScript selection, it will also create a test, but this time, because the test is already in a Test Suite, it will not create a new Test Suite.

Other operations on the menu are documented with tooltips.

A TestSuite instance is a Start Object and as such can be put directly on a Job's do_list.
Debugging For a video presentation of many of these concepts, please watch Debugging.
Most programmers spend most of their time debugging. Don't sweep this problem under the rug --- confront it with the following strategies:

Test Early and Often

We recommend entering just a bit of code at a time; a line or less before testing it. That way, when a bug shows up, you'll know it was in the last bit that you added.

Keep Backups

Before making a major change, copy the file your code is in and name the copy something like "orig_name_the_date.js" or "orig_name_before_implementing_foo.js". Then at worst, you can go back to previously working code.

Syntax Checker

DDE uses an automatic syntax checker named ESLint. It indicates syntax errors in the Editor pane as soon as you enter them. There are many different styles of JS coding and different versions of JS so its hard to get such errors correct. Even if you have syntax errors indicated, your code may run fine. As a first pass though, try to fix such errors before evaling. If you can't, go ahead and evaluate your code. Perhaps runtime errors will help you fix the bug, or perhaps it will run OK and you'll know to just ignore the JS Pane syntax bug indication.

Click on Delimiter

Many syntax errors occur because of unmatched delimiters. Click on an open or closed paren, square bracket or curley brace. It should highlight in green, and highlight its corresponding delimiter in green as well.

Selective Eval

Evaling just selected portions is another way to isolate bugs. If there is a selection of JavaScript code, only that code will be evaled when you click

Comment Out Code

Another technique is to comment out code until your bug goes away.
// comments out to the end of the line.
/* comment */ Wrap JavaScript in
slash-star ... star-slash
to comment out code in the middle of a line or multiple lines. See the Editor pane's debugging menu items. The oldest and crudest debugging techique is embedding print statements in your code. DDE supports a number of these to make debugging easier.


Entering debugger; into the body of a JS function definition will set a breakpoint there. When debugger; is evaluated (after you call the function) and the Chrome Developer Tools window is open, execution will pause and highlight the debugger; statement in a copy of your source code. (To open the Chrome Developer Tools window, click right on any DDE pane and choose Inspect Element. Use the arrow buttons stepper buttons in the Developer Tools window upper right to step execution.

Rather than enter debugger; into your code, its often easier to select the code you want to step through and click the button. This works just like the button in that if there is no selection, all the code in the editor is stepped.

JS Idiosyncracies

Because JavaScript, like all popular textual programming languages, has not been designed carefully with the "user experience" in mind, it is full of idiosyncracies that make learning how to use it require remembering a lot of "gotchas". The web has pages on common JavaScript programming errors. A good one is: https://www.w3schools.com/js/js_mistakes.asp , incomplete, but a good start.


Sometimes computers just get screwed up. Booting often fixes such problems.
  1. You can start with quiting and relaunching DDE.
  2. If that fails, shut down your whole computer and restart it.
  3. If that fails, shut off Dexter and restart it.
Contact Please help us by emailing a bug report or suggestion to cfry@hdrobotic.com Take a look at the latest Release Notes and the Known Issues to avoid duplication.