Giter Club home page Giter Club logo

dde's People

Contributors

bcomnes avatar braddunagan avatar cfry avatar dependabot[bot] avatar jamesnewton avatar jameswigglesworth avatar lmarsbrown avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dde's Issues

No quick save keystroke (e.g. Alt-F,S or Ctrl+S)

Those of us who are in the habit of quickly saving our code as we type by pressing Alt-F and S or Ctrl+S will be shocked to find that neither of those actually save anything.

Suggestion: Adding keyboard accelerators for File / Save would Save programmers a lot of lost time when DDE gets into a mode that prevents us from saving.

Fix CI

Getting started on some of the chores we discussed previously, First up, fixing DDE's CI system.

Appveyor + electron builder seems to be having some issues, so rather than fix those, I proposed we switch to GitHub actions, a CI system native to GitHub. Also, since GitHub is Microsoft now, it supports very decent windows build environments (unlike Travis last we checked).

Here is the plan:

  • Set up actions for windows, Mac and Windows.
  • Turn off travis and appveyor.
  • Ensure our release process works the same or closely resembles our previous process.

Assure Node v18 for fetch

let file_info_response = await fetch(full_url) // unnecessary to specify the no-cors, but it doesnt' hurt, {mode: 'no-cors'})

The line above affects the running of the job engine. This line uses fetch, which is provided by Node v18. We could prevent the server from building/running if node isn't version 18, or we could use NVM to cause node to be version 18.

Emergency stopping Dexter from DDE

If there is a long instruction running,
(such as in calibrate with a slow speed, move_all_joints can
take 5 minutes)
then clicking the stop button sends an "empty instruction queue now (E oplet )
cmd to dexter but that doesn't stop an ongoing instruction.
It may be the case the "E" doesn't empty the queue as it is
intended to.

Provide DDE4 installers

Targeted platforms:

  • Linux
  • macOS
    • ARM
    • Intel
  • Mobile?
    • Android?
    • iOS? (iPadOS?, watchOS?)
  • Windows

Certain Point Sets cause end of DXF file to not be processed

With some, but not all, sets of points, when processing a DXF file or text_to_lines string, the last several lines or part of a letter are simply not drawn, and the end effector stops while in contact with the drawing plane. To compensate, an "e" or other letter with a curved segment was added for the demo. Other point sets, which wrote at right angles to the original, processed all the data and the end effector was raised above the plane at the end.

The specific point sets which causes this problem were, sadly, lost. I will try to re-create the issue if that will help.

MIDI sound on Windows 10

Is there a forum for this project? I ask since this comment is more appropriate for a forum than an issue report.
In the DDE documentation for MIDI setup on Windows one can find this request "Please tell us if you've had success here and what you did to achieve it." This is what worked for me:
I installed http://coolsoft.altervista.org/en/virtualmidisynth#soundfonts
Then downoaded and extracted "FluidR3 GM Bank" from:
http://www.synthfont.com/soundfonts.html
From VirtualMIDISynth I imported the "FuidR3 GM Bank" sound fonts.
Restarted DDE load a MIDI example code and eval it.

Dexter can't receive instructions right after turning on

When trying to run a DDE Job that
sends instructions to a robot right after
turning the robot on, a bad error happens
that's hard to recover from.
James H didn't recall this happening in the
robot's that have "the dance", maybe simply because
when the robot is dancing, the operator
knows not to attempt to send something to
the robot.
In any case, waiting a while after turning
dexter on (a minute? not sure)
it seems to be ok.
So that's the workaround.
But this is just a workaround, we can't
expect our users to do this.
We need some kind of a signal from
Dexter to DDE, or for DDE to do some
kind of polling , or simply having
Dexter handling gracefully instructions
when its not quite ready to.

In Job Engine, espeak talks on top of itself.

the exec function returns instantly and continues to run espeak in the background, so that it's possible to call speak again. If speak is called multiple times, all the message appear on top of each other.

We fixed this once,
HaddingtonDynamics/Dexter#72 (comment)
but the fix wasn't incorporated and the code in DDE has changed enough that it needed to be re-implemented. I know the code below is working on my robot using job engine version 3.5.2, and I /think/ this will not cause problems going forward.

var to_speak = []
function speak({speak_data = "hello", volume = 1.0, rate = 1.0, pitch = 1.0, lang = "en_US", voice = 0, callback = null} = {}$
    if (arguments.length > 0 && speak_data != null) {
      var speak_data = arguments[0] //, volume = 1.0, rate = 1.0, pitch = 1.0, lang = "en_US", voice = 0, callback = null
      //out("speak_data:"+speak_data);
      }
    var text = stringify_for_speak(speak_data)
    if(window.platform == "node"){
      if (speak_data != null) { //new speech text
        let speak_cmd = "espeak \"" + text + "\" -a "+ (volume*200) + " -p " + (pitch * 50) + " -s " + (rate * 37 + 130)
        to_speak.push(speak_cmd)
        //out("saylater:"+speak_cmd)
        }
      else { //finished speaking prior text
        if (to_speak.length > 0) { //say what's on the stack, dump, and call again with null
          //out("saying: "+to_speak[0])
          exec(to_speak[0], function(){ to_speak.shift(); speak({speak_data:null}); })
          }
        else {
          //out("done saying");
          if (callback) callback();
          }
        }
      if (to_speak.length == 1) { //last one
        //out("lastword:"+to_speak[0])
        exec(to_speak[0], function(){ to_speak.shift(); speak({speak_data:null}); })
        }
      }
    else {
        var msg = new SpeechSynthesisUtterance();
//.... same from here down.

Unable to install DDE 3.6.3 as Job Engine on Dexter

Pulling down the current release of DDE, version 3.6.3, and installing it as a new job engine fails during install. See the console output below, and attached log file. The issue this time appears to be
https://github.com/tessel/node-usb
which may be a require from serialport (because that was the prior item) or might be something else.
It's trying to find a pre-built binary for the given version of node, arm processor, and linux, but those aren't available, so it tries to build from source, and fails while building libusb/os/linux_udev.o without finding a file called libudev.h

Console messages:

root@localhost:~/Documents/dde# npm install
npm WARN deprecated [email protected]: three-js exposes real modules now via three/examples/jsm/...
npm WARN deprecated for example to import Orbit, do
npm WARN deprecated import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
npm WARN deprecated
npm WARN deprecated [email protected]: Starting with three.js r103, GLTFLoader is included in the three package itself and installing three-gltf-loader is no longer necessary. It can be imported from 'three/examples/jsm/loaders/GLTFLoader'

> @serialport/[email protected] install /root/Documents/dde/node_modules/@serialport/bindings
> prebuild-install --tag-prefix @serialport/bindings@ || node-gyp rebuild

prebuild-install WARN install No prebuilt binaries found (target=11.6.0 runtime=node arch=arm libc= platform=linux)
make: Entering directory '/root/Documents/dde/node_modules/@serialport/bindings/build'
  CXX(target) Release/obj.target/bindings/src/serialport.o
  CXX(target) Release/obj.target/bindings/src/serialport_unix.o
  CXX(target) Release/obj.target/bindings/src/poller.o
  CXX(target) Release/obj.target/bindings/src/serialport_linux.o
  SOLINK_MODULE(target) Release/obj.target/bindings.node
  COPY Release/bindings.node
make: Leaving directory '/root/Documents/dde/node_modules/@serialport/bindings/build'

> [email protected] install /root/Documents/dde/node_modules/usb
> prebuild-install --verbose || node-gyp rebuild

prebuild-install info begin Prebuild-install version 5.3.6
prebuild-install info looking for cached prebuild @ /root/.npm/_prebuilds/2b648a-usb-v1.6.3-node-v67-linux-arm.tar.gz
prebuild-install http request GET https://github.com/tessel/node-usb/releases/download/v1.6.3/usb-v1.6.3-node-v67-linux-arm.tar.gz
prebuild-install http 404 https://github.com/tessel/node-usb/releases/download/v1.6.3/usb-v1.6.3-node-v67-linux-arm.tar.gz
prebuild-install WARN install No prebuilt binaries found (target=11.6.0 runtime=node arch=arm libc= platform=linux)
make: Entering directory '/root/Documents/dde/node_modules/usb/build'
  CC(target) Release/obj.target/libusb/libusb/libusb/core.o
  CC(target) Release/obj.target/libusb/libusb/libusb/descriptor.o
  CC(target) Release/obj.target/libusb/libusb/libusb/hotplug.o
  CC(target) Release/obj.target/libusb/libusb/libusb/io.o
  CC(target) Release/obj.target/libusb/libusb/libusb/strerror.o
  CC(target) Release/obj.target/libusb/libusb/libusb/sync.o
  CC(target) Release/obj.target/libusb/libusb/libusb/os/poll_posix.o
  CC(target) Release/obj.target/libusb/libusb/libusb/os/threads_posix.o
  CC(target) Release/obj.target/libusb/libusb/libusb/os/linux_usbfs.o
  CC(target) Release/obj.target/libusb/libusb/libusb/os/linux_udev.o
../libusb/libusb/os/linux_udev.c:40:21: fatal error: libudev.h: No such file or directory
compilation terminated.
libusb.target.mk:138: recipe for target 'Release/obj.target/libusb/libusb/libusb/os/linux_udev.o' failed
make: *** [Release/obj.target/libusb/libusb/libusb/os/linux_udev.o] Error 1
make: Leaving directory '/root/Documents/dde/node_modules/usb/build'
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:262:23)
gyp ERR! stack     at ChildProcess.emit (events.js:188:13)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:254:12)
gyp ERR! System Linux 4.4.30-xillinux-2.0
gyp ERR! command "/usr/bin/node" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /root/Documents/dde/node_modules/usb
gyp ERR! node -v v11.6.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok
npm WARN [email protected] requires a peer of @types/three@* but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] No repository field.

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: `prebuild-install --verbose || node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2020-11-03T23_41_34_149Z-debug.log
root@localhost:~/Documents/dde# node -v
v11.6.0

Simulator takes near 100% CPU on Ubuntu 18.04

DDE version since the new simulator was added cause the CPU's to run near 100% on this one computer. On a very simular machine, running Ubuntu 16.04, there is no issue. The GPU cards (and so drivers) are different, so that might be an issue. The versions of node were different but that has been tested and made no difference. (e.g. the problem machine was changed to v10.11.0 which was used on the working machine).

Workaround: Don't start the simulator.

  1. Change the lower right panel to Make Instruction or any option other than Simulate Dexter. This alone will NOT stop the simulator.
  2. Exit DDE
  3. Open DDE

Just ever opening the simulator allows DDE to work on 18.04 without excessive CPU / GPU work.

This is a very minor issue and shouldn't be a worry unless Ubuntu 20.04 has the same problem. That needs to be tested.

Simulated robot not showing up in v3.8.0

When opening the simulator panel on a freshly installed version of DDE, the robot may not show up at all, or just the top of it may be visible upside down in the window.
image

To work around this problem, pull down the File menu and select New:
image
paste this code into the main editor panel:

persistent_set("dde_window_width",outerWidth);
persistent_set("dde_window_height",outerHeight);
location.reload();

click the Eval button below the editor window.

That should fix the window sizing and then reload the window

This bug should be fixed by
#72
if that is accepted in the next release.

Calibrating another robot when there is no dexter0

When calibrating a dexter that is NOT dexter0,
and there's no dexter0 connected to DDE,
there's an error, that's at the very least confusing,
because dde is attempting to contact
dexter0 for no good reason. (and it shouldn't
be doing that!)

To diagnose this, I searched though all
of DDE's uses of dexter0,
and didn't find anything particularly suspicious.
Then I read by hand the 5 files under the
low_level_dexter folder.
My guess is the problem comes when there
is a job created for calibration who's
robot defaults to dexter0 when it shouldn't.

Below are my notes of code that looks
suspicious, especially the last one:

find_home_for_DDE_2.js line 38

  • find_home_get_robot returns dexter0 obj
    but what if there's no robot at that ip address?
  • The job FindHome may default its robot to dexter0.
    ViewEyeRealTime.js line 169
    var ip_address = Job.CalSensors.robot.ip_address
    var path = "//" + ip_address + "/share/AdcCenters.txt"
    write_file(path, content)
    If there's nothing at that ip address, derived from a robot
    that might be dexter0, we have a problem

ezTeach.js line 160 calling init.

ezTeachBase.js line 66

calibrate_optical.js defines job Calencoders defaulting robot to dexter0
but calibrate_ui.js line 275: is Job.CalEncoders.start({robot: cal_get_robot()})
If this is the only place Caelncoders is started, ok,
but if user starts it from the jobs bar, it will use dexter0.
However, this code is in a TRY so ought to protect against bad ip_address

ViewEyeRealTime, line 214 defines job CalSensors whose robot
default to dexter0
right after the def is
let ip_address = Job.CalSensors.robot.ip_address
let path = "//" + ip_address + "/share/AdcCenters.txt"
so its really trying to use that ip_address of dexter0
even without running the job. Looks bad.

JamesW, I hope you can look at these
code snippets and image what will happen
if there is no dexter0.
Maybe just try running Caibrate
without a physical dexter0, see what breaks
and think about better error messages
or whatever. I'm happy to consult.

undefined error in call to classifier.detectMultiScale for face detection demo

The following code, adapted from:
https://docs.opencv.org/3.4.1/js_face_detection_camera.html
and the webcam DDE example:
https://github.com/cfry/dde/blob/master/examples/opencv_process_webcam.js
Generates the following error:

While calling the show_window handler function of: handle_webcam_video,
undefined
Error at dde_error (file:///C:/Program%20Files/dexter_dev_env/resources/app.asar/utils.js:29:15) at HTMLInputElement.window.submit_window (C:\Program Files\dexter_dev_env\resources\app.asar\output.js:641:9)

After staring at it for rather a long time, I've found I have no clue how to debug that. I'd like to learn how to debug as much as I'd like to see this fixed.

//inspired by https://davidwalsh.name/browser-camera

var cv = require("opencv.js")
let faces = new cv.RectVector();
let classifier = new cv.CascadeClassifier();

function handle_webcam_video(vals){ //vals contains name-value pairs for each
    //html elt in show_window's content with a name.
    if(vals.clicked_button_value == "init"){ 
// Clicked button value holds the name of the clicked button.
        if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
            navigator.mediaDevices.getUserMedia({ video: true }).then(function(stream) {
                video_id.src = window.URL.createObjectURL(stream);
                video_id.play();
            })
        }
    }
    else if (vals.clicked_button_value == "Snap Photo"){
        let context = canvas_id.getContext('2d')
        context.drawImage(video_id, 0, 0, 320, 240)
        let mat          = cv.imread(canvas_id)
        let grey_mat      = new cv.Mat(700, 700, cv.CV_8UC1)
        cv.cvtColor(mat, grey_mat, cv.COLOR_RGBA2GRAY)
        let dst      = new cv.Mat(700, 700, cv.CV_8UC1)
        cv.cvtColor(mat, dst, cv.COLOR_RGBA2GRAY)
        cv.imshow("out1_canvas_id", grey_mat)
		classifier.detectMultiScale(grey_mat, faces, 1.1, 3, 0);
        for (let i = 0; i < faces.size(); ++i) {
            let face = faces.get(i);
            let point1 = new cv.Point(face.x, face.y);
            let point2 = new cv.Point(face.x + face.width, face.y + face.height);
            cv.rectangle(dst, point1, point2, [255, 0, 0, 255]);
        }
        cv.imshow('out2_canvas_id', dst);
        mat.delete()
        mod_mat.delete()

    }
}

show_window({content:
    `<input type="button" value="init" style="margin-left:4px;"/> 
  &nbsp;webcam video display.
 <input type="button" value="Snap Photo" style="margin-left:115px;"/>
  &nbsp;from webcam video.<br/>
 <video  id="video_id"  width="320" height="240" style="border-style:solid; border-width:1; margin:3px;" autoplay></video>
 <canvas id="canvas_id" width="320" height="240" style="border-style:solid; border-width:1; margin:3px;""></canvas><br/>
  &nbsp;Photo processed to Black and White. 
</span><br/>
 <canvas id="out1_canvas_id" width="320" height="240" style="border-style:solid; border-width:1; margin:3px;""></canvas>
 <canvas id="out2_canvas_id" width="320" height="240" style="border-style:solid; border-width:1; margin:3px;""></canvas>

 `,
    title: "Processing Webcam video with DDE and OpenCV",
    width: 700, height: 600, x: 300, y:25,
    callback: handle_webcam_video})

Joint 3 calibration limits a bit too far?

At least on my Dexter, the max positive angle is 152 (vs 153 default) on Joint 3. If it's just mine, the workaround is easy: Just edit the value. If' other people find the same thing, the default should probably be changed.

ViewEye bug

Joint 3 default range is backwards
instead of 153 to -153 it should be
-153 to 153

new Serial robot doesn't track the port object, can't close port when closing robot

The low level serial connect code adds the serial port object into the serial_path_to_info_map entry when it opens a port, and so when the low level close is called, the port can be closed.

The high level serial code does NOT save the port object, but then tries to use it to close the port when the serial robot is closed. This fails, and now no other robot can use that port because it is lost.

(writing this to remind myself to fix it tomorrow am. It's late and I just found this bug, too tired to fix it)

Cal saving blank AdcCenters.txt files

If Cal can't read the AxisCal.txt AdcCenters.txt file from the robot but can still write to it, the file it creates will have all 0's in it except the center for the current joint.

Also a "save as" button should be added for the option to save the file somewhere besides on the robot.

Getting out of the selection help mode

Select an object in a program in the editor. Copy it with Ctrl+C, then try to use the arrow keys to move to the location you wish to paste that value. Instead, the selection is changed to the next or prior value that it might have.

e.g. In the line:
var len = my_array.length
select "length", Ctrl+C, and press left arrow. The selected text changes to "lastIndexOf"

Workaround: Press Ctrl+V to paste the copied text back in and remove the selection.

Suggested fix: If the text has just been copied to the clipboard, disable the changing of the text.

load_files vs file_content unclear

load_files evals the file where file_content gets the file but doesn't eval it.

The name of the function load_files doesn't indicate what the function actually does. Perhaps eval_file would be better? or load_eval_file?

Right arrow doesn't work while selecting

  1. Click anywhere in a program in the editor
  2. Hold down the shift key, and press the right arrow. Nothing happens.
  3. Hold down the shift key, and press the LEFT arrow, selecting some text, and then press the right arrow to reduce the size of that selection. The selection is not reduced.

Dexter.move_all_joints sends incorrect values for Joints 6 and 7

Dexter firmware has been updated (on it's own branch, ready to pull) to accept 2 additional values on the "a" (move all joints) instruction and send those out to set gripper roll and span. This integrates the 2 new servo joints into the move all joints system, bringing it from 5 joints to 7 joints.

However, DDE may not correctly send these values as of 2.5.3. This may happen even when only 5 values are sent in the DDE Dexter.move_all_joints command as it will try to guess where Joints 6 and 7 were before. There are two problems:

  1. DDE is incorrectly converting the Joint 6 and 7 values. It seems to always send 3600 for joint 6 and 7200 for joint 7. There is some question as to what the values sent should be. Either:
  • The value should be in arcseconds and the firmware should be updated to convert that to degrees for the Dynamixel servo, or
  • The value should be sent in degrees and the Firmware should just pass it through. (current)
  1. The initial values for these joints may not be set correctly.

Also, because the SetParam EERoll and EESpan commands also set the End Effector positions (which are Joints 6 and 7), DDE may not correctly track the commanded position, and if a 5 axes Dexter.move_all_joints command is issued, it will assume the user wants Joint 6 and 7 at their last known position, which may be different from where they are now due to the EERoll and EESpan SetParm commands. Either:

  1. DDE could just NOT send positions when it isn't given position for higher order joints. This seems safest.
  2. DDE could monitor the EERoll and EESpan commands to stay in the loop on their commanded positions.

See also:

HaddingtonDynamics/Dexter#36

read_from_robot does not work in DDE v 3.1.0

When starting the calibration window it tries to do a read_from_robot to get the Eye Centers.
This fails in the current version of DDE (3.1.0) and hangs up on
"Attempting to read AdcCenters.txt from robot with IP: 192.168.1.142..."

This is done again with the same image and with DDE 2.5.13 (LTS) and it works.

Get build to work with `windows-latest`

The following is where windows-latest was changed to windows-2019, so that the build would pass:
59a4852#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721R62

commit 59a48522bd4b70fdf9dadd2c6f0476d0c49339c1
Date:   Tue Feb 8 13:29:47 2022 -0800
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -62 +62 @@ jobs:
-    runs-on: windows-latest
+    runs-on: windows-2019

One reason why it might be necessary to get the build to work with windows-latest, as opposed to windows-2019, is that it might be possible that there could be some security issue with using windows-2019 instead of windows-latest.

Can't connect to Dexter, "Warning: Dextersim.send doesn't know what to do with the legal oplet: w"

When I upgraded and try to run my version of forcePlay.js, all I got after pressing any button was
"Warning: Dextersim.send doesn't know what to do with the legal oplet: w"

It apparently modified my dde_init.js file to the following:
`persistent_set("ROS_URL", "localhost:9090") //required property, but you can edit the value.
persistent_set("default_dexter_ip_address", "192.168.1.142") //required property, but you can edit the value.
persistent_set("default_dexter_port", "50000") //required property, but you can edit the value.
//This file is loaded when you launch DDE.
//Add whatever JavaScript you like to the end
//just before the call to "out" in the last line.

//To change DDE colors,
// 1. Uncomment the below line(s).
// 2. Select the first arg.
// 3. Choose Insert menu "Color" item.
// 4. After inserting the new color, eval the "set_" call.
// 5. To get the default color, just comment out the line and relaunch DDE.
// set_window_frame_background_color("#ff8c96")
// set_pane_header_background_color("#e39f5a")
// set_menu_background_color("#ff8c96")
// set_button_background_color("#ff8c96")

persistent_set("default_dexter_ip_address", "192.168.0.142") //required property but you can edit the value.
persistent_set("default_dexter_port", "50000") //required property, but you can edit the value.
new Dexter({name: "dexter0"}) //dexter0 must be defined.

new Dexter({name: "dexter0"}) //dexter0 must be defined.
`
adding the three new lines at the top:

persistent_set("ROS_URL", "localhost:9090") //required property, but you can edit the value.
persistent_set("default_dexter_ip_address", "192.168.1.142") //required property, but you can edit the value.
persistent_set("default_dexter_port", "50000") //required property, but you can edit the value.

and the extra
new Dexter({name: "dexter0"}) //dexter0 must be defined.
to the bottom.

This contradicts the following statement in the documentation under "Updating to the latest DDE": "Follow the directions under First Install above. This will not change any files in your dde_apps folder."

Issues with the serial port only working once in DDE.

DDE uses the NPM package "SerialPort" to communicate via serial devices. It is currently using version 8:
https://serialport.io/docs/8.x.x
Carefully reading and following the documentation for that object is critical. Especially:
https://serialport.io/docs/8.x.x/api-stream

One problem we have had in the past is that we close the port, and then delete the reference to the serial port object from the map. If the close fails, or isn't a complete close, then we have lost the ability to access that port object. Why the port doesn't close and release the object is the question.

It MAY be that this describes the issue:
https://stackoverflow.com/questions/46307803/nodejs-serialport-re-establish-connection-to-port-after-closed
see this microscopic bit of cryptic documentation:
https://serialport.io/docs/8.x.x/api-stream#serialportresume

Another possibility is that the issue comes from the "port" and the "stream" being two different things. The SerialPort library documents these separately:
https://serialport.io/docs/8.x.x/api-serialport
https://serialport.io/docs/8.x.x/api-stream
Only the stream API has a close method, but maybe that doesn't close the serial port?

But our solution has just been to /never/ close the port once it's open. So the logic is:

  • Check if the port object exists. If so, just use it. (we can use the SerialPort.update method to change baudrates, etc... ). If not, open the port and wait for the call back indicating it's open, or for the open event to fire.
  • When we are done, do NOT close the port, just flag it and ignore everything that comes in.

This comment on this issue (scroll down to the bottom) may be helpful:
HaddingtonDynamics/Dexter#60 (comment)

WinOS Installation Hangs Bug

WinOS Installation Bug
Symptom: While installing DDE on WinOS 7, 10, and maybe others,
you get a dialog box that says "Installing, please wait..."
whose progress bar stops progressing and you have to wait for more than 1 minute.
WorkAround:

  1. Close the dialog box.
  2.          Win7:  choose Start menu/Control Panel/Programs and Features
    
  3.          Win10: choose Start menu/Windows System/Control Panel/Programs and Features     
    
  4.          Click right on "dexter_dev_env".
    
  5.          Choose "uninstall"
    
  6.          You may get a dialog that says: 
    
  7.             "An error occurred while trying to uninstall...
    
  8.              Would you like to remove ..."
    
  9.              Click the "Yes" button.
    
  10.          Double click on Downloads/dexter_dev_env-setup-(version number).exe  to reinstall. 
    
  11.          DDE Should install in 1 minute or less.
    

Why this happens: If you rename or remove C:\Program Files\dexter_dev_env
it screws up the windows registry, and the DDE installer program can't handle it.
Electron Apps (like DDE) use a program called NSIS for installation, and it has this, ahem, feature.

persistent_get doesn't use callback?

The current definition of persistent_get appears to completely ignore the second parameter (callback) instead simply returning the retrieved value, but the docs clearly indicate this the callback should be used to access the returned data.

Docs out of date?

Serial encoding issues with binary data. aka the FD problem.

When communicating with a serial device which needs to receive or which will send, binary data, meaning character values over 127, you may find that those values get converted to 'fd' for some unknown reason.

The reason is the bane of my existence: UTF-8.

UTF-8 came from the Unicode effort which was designed to support character sets for languages other than English. English uses only 26 letters, a-z, but there are upper and lower case versions of those so 52 characters. Of course we also need to be able to present the Arabic numerals 0-9 so 62. And then spaces, punctuation marks, etc... perhaps 90 total printable symbols. But don't forget control characters, and then there are latin symbols, accent marks (one for each letter that might need one). We end up pretty much filling up 128 characters. That will fit in 7 bits and ASCII (American Standard Code for Information Interchange) was born. This almost uses up the basic 8 bits available computers work on, so there are actually another 128 characters available from 128-255, which were used for all sort of tricky things; line drawing, graphics, and so on. And for many years, that was good enough.

But there are other countries and other languages and they should be supported. Many other language have a large number of characters, so more than 8 bits are needed. When Javascript was written, it settled on 16 bits, and the UTF-16 set.
https://developer.mozilla.org/en-US/docs/Web/API/DOMString/Binary
"In JavaScript strings are represented using the UTF-16 character encoding: in this encoding, strings are represented as a sequence of 16-bit (2 byte) units. Every ASCII character fits into the first byte of one of these units, but many other characters don't."

So when you set e.g. var myStr = "ABC" what is actually stored in memory is (in hex) 00 40 00 41 00 42 where 40 is the ASCII code for A (again, in hex). In other words, every byte in the string is a 16 bit word where the bottom 8 bits are actually the value you expected and the top 8 bits are zero. If you need to encode a line of Kangi, or CCCII (Chinese version of ASCII), no problem, you have those extra 65536 - 256 characters to do it in.

But now, think about this: You write that string to a file. Then you open that file in a standard text editor. And it has nulls between every letter. Oops. They could just write out only the low byte, and that would work perfectly for ASCII strings. But what about UTF-16 character sets? Hmmm... They could write those out in UTF-16 just as stored in RAM, but then how would it know which format was used to write the file when you wanted to read the file back in?

So someone had the brilliant idea of creating UTF-8. This uses the same ASCII characters for all values between 0 and 127. But then if you want to write a 16 bit character, it writes out 3 bytes: A "flag" byte which would be C2 (in hex) and then the two bytes of the 16 bit value. When reading the file, that C2 will tell the program that this is not a standard ASCII file and it will decode the next two characters as a 16 bit value. If you want to write an atual C2 in the file, it will write a C1 then C2; the C1 meaning "flag the next byte as a single binary value" and the C2 being the value. In this way, every possible 16 bit value would always make the round trip from RAM to file and back correctly, and ASCII data would still look like ASCII... as long as it didn't use the top bit. And really, ASCII isn't supposed to use that top bit.

Win, win and dusted right?

Well... no. Because what about binary data? e.g. straight 8 bit data which isn't ASCII, but is still stored in a string? Well, first, you aren't supposed to use Strings for binary data, that's what buffers are for. But learning to do things with a new datatype? Pffft. DDE sends and receives data over the serial port as Strings like god intended. And that is probably the best design because most users will send and receive ASCII data and expect to work with Strings.

But when you need to send / receive binary data? Well the npm SerialPort library sets the encoding to UTF-8 by default. Not sure why... for files, yeah... for serial data? Lucky us, we can change that:
https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings

var port_path = "/dev/ttyUSB0" // "COM4" //last(serial_devices()).comName 

var acc_data="" //a variable to accumulate data into. Actually need one for each port. 
var data_pause //the setTimeout ID

function myOnReceiveCallback_low_level(data, port) {
    acc_data += data
    clearTimeout(data_pause)
    data_pause = setTimeout(
    	function() {
	out(acc_data.split('').reduce((s,i) => s+("0"+i.charCodeAt(0).toString(16)).slice(-2)+" ", ''))
            acc_data=''
			}
		, 100
		)
	}

serial_connect_low_level(port_path
    , {baudRate: 115200}
    , capture_n_items=0
    , item_delimiter=""
    , trim_whitespace = false
    , parse_items=false
    , capture_extras=false
    , callback=myOnReceiveCallback_low_level
    //, error_callback=onReceiveErrorCallback_low_level
    //, open_callback=onOpenCallback_low_level
    //, close_callback=onCloseCallback_low_level
    ) 
var port_info = serial_port_path_to_info_map[port_path]

//need binary encoding. 
port_info.port.setEncoding("binary")

//Make a "binary" string from HEX data
var dmi820get = ""
"68 04 00 04 08".split(" ").forEach(str => {
  dmi820get += String.fromCharCode(parseInt(str,16))
})

//If we use the built in send it dumps binary data to the Output panel
//serial_send_low_level(ard_path, dmi820get) 
//but we can replace it:


function dmi820_get_data(port_info) {
    if (port_info){
        let arr =
            port_info.port.write(dmi820get, 
                                 function(error){ //can't rely on this getting called before onReceived so mostly pretend like its not called, except in error cases
                if (error){
                    dde_error("In serial_send callback to port_path: " + port_path +
                              " got the error: " + error.message)
                }
                else {
                    //out("serial write just sent: " + dmi820get)
                }
            }
                                )
        }
	}
dmi820_get_data(port_info)

Long story only slightly longer. This cost me a day. I see absolutely no reason for the encoding in a serial data transfer to be UTF-8. I would propose that in DDE, every serial port opened be set to "binary" encoding via .setEncoding("binary") as shown in the sample. It shouldn't mess up standard ASCII data (that should be tested), and it will allow us to communicate with binary devices.

Control.loop popup help doesn't work.

If you have a Control.loop or Robot.loop in the do_list, and you click on it, it does not lead to the entry in the Doc for Control.loop.

For Robot.loop, it shows the function, for Control.loop, it shows something about an HTML attribute?

.joint_angles() does NOT return joint angles.

The .joint_angles(), and .robot_status[Dexter.J1_ANGLE], etc... do NOT feedback the
actual angle of the joint from the robot.

.robot_status[Dexter.J1_FORCE_CALC_ANGLE] etc... appears to return the joint angles.

I'm not sure if that is a DDE operational error or a documentation error.

speak voices all sound the same

speak({speak_data: "Level.", voice: 0} through speak({speak_data: "Level.", voice: 3} all appear to be the same female voice.

Access to the file share on Dexter OS is blocked by Windows 10

(documenting this here because I don't see it, although I know we are aware of it)

The suggestion has been made to move to an HTTP socket based file data exchange. This requires the DexRun.c program be updated to support commands for the transfer of file and directory data. E.g. a letter needs to be assigned to a command, and the block of data transferred would be a path or file name as well as a block number since data blocks are of limited size.

Suggested operations

  • Get folder item count: If the command is for a directory, and block 0, the returned data would be the number of files and folders under that dir.

  • Get folder item data: Then each would be iterated by repeating the directory and using block 1, 2, 3... for each folder/file in the dir. In that case, the return data would be the file name, size, and any other important properties.

  • Get item size: To access a file, first the file path/name would be sent and then block 0 would return the size of the file in blocks

  • Get item data: To get the actual file data, the block numbers 1,2,3... are sent and each returns that block of data from the file. On the Dexter side, it can be assumed that the file will be read out in block order, so the standard sequential fgets should be fine. Dexter just needs to track the block expected vs the block it's on (by count of calls to fgets with block size buffer) and then send back an error with the current block number if there is an issue. A lost block would, however, require reseeking... I think that can be done with lseek... might be better to close the file after each block and when reading block X, open the file, lseek to that position (block size * block number) and then gets a block.

  • Put item data: Same as before, but it's writing that block of data to the file. Because the data is now flowing from DDE to Dexter, sending the path each time wastes block space, so maybe Dexter just writes to whatever the last file that was read? So we only send the block number and the rest of the buffer is file data. Block size is buffer size less the size of the block number.

C functions (I think this works in Linux) to get info on a directory:
http://techref.massmind.org/techref/language/ccpp/cref/FUNCTIONS/directory.html

Open a file:
http://techref.massmind.org/techref/language/ccpp/cref/FUNCTIONS/fopen.html

Read data from a file:
http://techref.massmind.org/techref/language/ccpp/cref/FUNCTIONS/fgets.html

Move to a location in a file:
http://www.massmind.org/Techref/language/ccpp/cref/man/lseek.htm
(it may be fseek is right... I haven't done this is a long time)

Write data to a file:
http://www.massmind.org/techref/language/ccpp/cref/man/fputs.htm

If I can get my Dexter setup for development, and this seems good, I'll be happy to try to work on the c code.

Cannot Input Characters into Editor

Version 3.8.0

Issue:
open DDE -> input characters into any file using Editor -> switch open files -> cannot add characters but cannot delete characters in any file, also cannot input text into any other text boxes in DDE

Mitigation:
clicking outside of DDE i.e. on taskbar, selecting a new app etc. allows editing of any file once again until you try to edit a different file, the issue occurs again ad infinitum

Job / Cal does not calibrate entire joint.

Selecting Job / Cal and then selecting at least joint 4 (and I think all joints?) does not actually process the entire rotation of the joint. As a result, errors in the encoder disk, or its alignment, are not seen. Also, changes in the "eye" opening as a result of even minor alignment changes from one end of the rotation to the other are not detected.

This was the cause of the "freak out" in my Dexter arm, which is now resolved.

[Linux] desktop file is lacking a Categories= entry

The desktop file is lacking a Categories= entry in the *.desktop file.

According to the menu spec,

By including one of the Main Categories in an application's desktop entry file, the application will be ensured that it will show up in a section of the application menu dedicated to this category. If multiple Main Categories are included in a single desktop entry file, the entry may appear more than once in the menu.

Hence, please add at least one of the following in the Categories= key.

Main Category Description Notes
AudioVideo Application for presenting, creating, or processing multimedia (audio/video)
Audio An audio application Desktop entry must include AudioVideo as well
Video A video application Desktop entry must include AudioVideo as well
Development An application for development
Education Educational software
Game A game
Graphics Application for viewing, creating, or processing graphics
Network Network application such as a web browser
Office An office type application
Science Scientific software
Settings Settings applications Entries may appear in a separate menu or as part of a "Control Center"
System System application, "System Tools" such as say a log viewer or network monitor
Utility Small utility application, "Accessories"

In addition, you could specify one or more from the longer list of Additional Categories.

Please test the result with desktop-file-validate and make sure it passes.

electron-builder offers native support for this since v19.22.1.

Reference: AppImage/appimage.github.io#2

Clicking on the link to the youtube video loses you work.

  1. Write code for 30 minutes without saving.
  2. Click the link for "Video tutorial of DDE" under Users Guide, User Interface
  3. Try for 10 more minutes to find a way to get back into DDE and save your code.

Workaround: NEVER fail to save your code constantly. Duh.

Suggested fix: Open links in a new browser window.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.