Skip to content

Commit

Permalink
many things
Browse files Browse the repository at this point in the history
  • Loading branch information
Fry authored and Fry committed Mar 17, 2017
1 parent e857e74 commit 80e866f
Show file tree
Hide file tree
Showing 11 changed files with 722 additions and 615 deletions.
824 changes: 324 additions & 500 deletions .idea/workspace.xml

Large diffs are not rendered by default.

13 changes: 11 additions & 2 deletions doc/guide.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
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.
<a href="http://hdrobotic.com/videos/">Videos on Dexter</a>
<a href="http://hdrobotic.com/videos/" target="_blank">Videos on Dexter</a>
<span id="dde_overview_id" style="color:blue; text-decoration:underline;">DDE Overview Paper</span>
</details>
<details><summary>Why Use DDE?</summary>
Expand Down Expand Up @@ -58,7 +58,16 @@
needs work
</details>
<details style="margin-left:20px;"><summary>Launch DDE</summary>
needs work
On Windows, the DDE application is installed in
<code>C:\Program Files\dexter_dev_env\dexter_dev_env.exe</code>
and on the desktop.<br/>
On Mac, <code>Macintosh HD/Applications/dever_dev_env.app</code>
<p/>
Double click on the file to launch DDE. If there is a file
<code>Documents/dde_apps/dde_init.js</code>, it will be
loaded automatically. 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.
</details>
</details>
<details><summary>Robot Configuration</summary>
Expand Down
10 changes: 9 additions & 1 deletion doc/known_issues.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
<details style="padding-left:20px;"><summary>Known Issues</summary>
<ul>
This version is the first in the new Electron framework.
It is made available only for testing purposes. It is not
well tested.
In general, users should not use it. Stick with the previous Chrome apps version
a while longer. Sorry.
<ul><li>Sending commands to hardware robot broken (but similation ok)</li>
<li>Speech recognition busted.</li>
<li>None of the apps for the 3 platforms are "signed", thus you get warnings
when installing them about being "untrusted".</li>
<li>Dexter.draw_dxf needs extension to describe the drawing plane.</li>
<li>Dexter.run_gcode needs many extensions.</li>
<li>Some instructions lacking sections in the Reference Manual.</li>
Expand Down
271 changes: 230 additions & 41 deletions doc/ref_man.html

Large diffs are not rendered by default.

75 changes: 73 additions & 2 deletions doc/release_notes.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<details style="padding-left:20px;"><summary>v 1.0.0, Feb 20, 2017</summary>
<details style="padding-left:20px;"><summary>v 1.0.4, Mar 16, 2017</summary>
Highlights: New Electron Framework, New instruction Robot.grab_robot_status,
Serial Port extensions, file access improved, dxf improvements.
Serial Port extensions, file access improved, dxf improvements,
go_to instruction and friends, better help in finding doc.
Please read Known Issues.
<ul>
<li>Electron Framework replaces Google Chrome App. Facilitates
single JavaScript environment and utilization of node.js packages.</li>
Expand Down Expand Up @@ -78,6 +80,9 @@

<li> newObject now ignores "name" arg if it is null or undefined.
But if it is some OTHER non-string, newObject errors.</li>
<li> <code>Root</code> is a new global variable that holds the
root of the object system. So all object systems paths should
now start with Root.</li>

<li> Dexter.draw_dxf fixed bug that ignored the 3rd argument and always treated it as 2000</li>
<li>Dexter.draw_dxf first argument is usually a string <= 512 long
Expand All @@ -100,6 +105,72 @@
<li> Replaced the individual videos with
just one url to the hdrobotic.com video page.
</li>

<li> new instruction Robot.label("a string"), its a no-op but provides
target for go_to.</li>

<li> new instruction Robot.go_to(instruction_location)
"jumps" the program counter. Lots of functionality in ref man doc.</li>

<li> Now clicking on TestSuite gives you click help with an underlined
"TestSuite" that you can click on to see documentation.</li>

<li>job.start now can take "program_counter" and its an instruction_location
to init the program_counter to something other than the first instruction.
The default is 0, meaning first instruction on do_list is the first one run.
Like "go_to" at the beginning of a job.</li>

<li> job.start now can take initial_instruction as an instruction to run first.
This replaces the old param to Job.start of "sent_from_job" which was
used when a non-started job was sent an instruction.
The new initial_instruction is much more general since it can be used
when creating a job, when calling Job.start or by send_to_job.
The default is "no instruction". When it exists and
a job is started, the initial_instruction is run just BEFORE the
instruction at the initialized program_counter (which defaults to 0).</li>

<li> The documentation "About" section now shows the release date of
the DDE version loaded.</li>

<li> load_files ref man documentation now has examples.</li>

<li> dde_init.js now documented (under "Installation/Launch DDE").</li>

<li> start method now takes a program_counter
program_counter: allow a new items: "highest_completed_instruction"
and "highest_completed_instruction_or_zero"
So that if the job errors, and pc init is "highest_completed_instruction_or_zero"
we DON"T reset the do_list to the orig do_list,
but keep it the same, and go and grab the id of the
instruction that errored and use it.</li>


<li> Instruction.Control.send_to_job no longer takes a "to_job_name"
as an explicit parameter, however,
the where_to_start param can be any instruction_location
used by Robot.go_to, or program_counter setting.
Can include a job property but defaults to "this job".</li>

<li> New static method Job: Job.insert_instruction(instruction, location )
where location same format as go_to, setting program_counter.</li>

<li> sent_from_job was documented but I've undocumented it.
Users should use new facilities in
new job and start's initial_instruction, Job.insert_instruction.</li>

<li> Instruction Robot.wait_until extended to take new value for
its argument "new_instruction" meaning
when wait_until first gets called, it captures the
instruction after it (which could be none, if the wait_until is
the last instruction), then waits until
the next instruction is different,
then it unpauses.
Often put on the end of a do_list, or maybe the only thing
initially on a do_list, and waits until something gets on it.</li>

<li> If the search type-in box is empty when you click the doc "Find" button,
the selected text in the Doc, JavaScript, or Output pane is used,
as noted in the new tooltip for the Find type-in box.</li>
</ul>
</details>

4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@
</div>
<div style="vertical-align:top;display:inline-block;line-height: 1.0;">font<br/>size:</div>
<input id="font_size_id" type="number" style="vertical-align:top; width:30px;" value="17" min="6"/>
<select id="file_name_id" style="width:360px;font-size:18px;"><option>new file</option></select>
<select id="file_name_id" style="width:360px;font-size:14px;"><option>new file</option></select>
ROS url: <input id='dexter_url' value="localhost:9090" style="font-size:14px;"/>
</div>
<textarea id="js_textarea" wrap="off" style="width:98%; height:84%; font-size:17px; font-family:monospace;padding:4px;"
Expand Down Expand Up @@ -543,7 +543,7 @@
<div id="doc_pane_id" style="font-size:16px;background-color:#e1e1e1;padding-left:5px;">
<div class="pane_header_wrapper" style="height:30px;">
<span id="documentation_pane_help_id" class="pane_header">Doc</span>
<input id="find_doc_input_id" placeholder="search string" style="width:100px;"/>
<input id="find_doc_input_id" placeholder="search string" title="If this field is empty,&#013;the selection in the&#013;Doc, JavaScript, or Output&#013;pane is used." style="width:100px;"/>
<button id="find_doc_button_id">Find</button>
<button id="eval_doc_button_id" title="Evaluated the selected code&#013;in the Doc pane.&#013;Result goes in the Output pane.ƒ">Eval Doc</button>
</div>
Expand Down
33 changes: 29 additions & 4 deletions instruction.js
Original file line number Diff line number Diff line change
Expand Up @@ -888,9 +888,7 @@ Instruction.Control.out = class Out extends Instruction.Control{
out(message, this.color)
job_instance.set_up_next_do(1)
}
toString(){
return "" + this.val
}
toString() { return "Robot.out of: " + this.val }
}

Instruction.Control.send_to_job = class send_to_job extends Instruction.Control{
Expand Down Expand Up @@ -974,7 +972,7 @@ Instruction.Control.send_to_job = class send_to_job extends Instruction.Control{
where_to_insert: params.where_to_insert, //just for debugging
wait_until_done: params.wait_until_done //just for debugging
})
Job.insert_instruction_at_location(sfj_ins, params.where_to_insert) //must do before starting or unsuspending
Job.insert_instruction(sfj_ins, params.where_to_insert) //must do before starting or unsuspending
if (to_job_instance.status_code == "not_started"){
if(params.start){
to_job_instance.start({initial_instruction: sfj_ins})
Expand Down Expand Up @@ -1347,6 +1345,33 @@ Instruction.Control.wait_until = class wait_until extends Instruction.Control{
job_instance.set_up_next_do(0)
}
}
else if (this.fn_date_dur == "new_instruction"){
const pc = job_instance.program_counter
const pc_on_last_instr = (pc == (job_instance.do_list.length - 1))
const next_instruction = (pc_on_last_instr ?
null : job_instance.do_list[pc + 1])
if (this.old_instruction === undefined){ //first time through only
this.old_instruction = next_instruction
job_instance.set_up_next_do(0)
}
else if (this.old_instruction === null){ //started with this instr as the last one
if (pc_on_last_instr) { job_instance.set_up_next_do(0) }
else { job_instance.set_up_next_do(1) } //got a neew last instr
}
else if (next_instruction == this.old_instruction){//no change so don't advance the pos
job_instance.set_up_next_do(0)
}
else { //got a new instruction since this instruction started running so execute it
job_instance.set_up_next_do(1)
}
}
else {
dde_error("In job: " + job_instance.name +
' in wait_until("new_instruction")<br/>' +
" got fn_date_dur of: " + this.fn_date_dur +
" which is invalid.<br/>" +
' It should be a function, a date, a number, or "new_instruction".')
}
}
}

Expand Down
80 changes: 24 additions & 56 deletions job.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ var Job = class Job{
shallow_copy(this.orig_args.user_data)
this.program_counter = this.orig_args.program_counter //see robot_done_with_instruction as to why this isn't 0,
//its because the robot.start effectively calls set_up_next_do(1), incremening the PC
this.initial_instruction = this.orig_args.initial_instruction
const sent_from_job = options.sent_from_job
delete options.sent_from_job //even if this field is not present, that's ok, this is a oop
this.initial_instruction = this.orig_args.initial_instruction //also used by sent_from_job

//first we set all the orig (above), then we over-ride them with the passed in ones
for (let key in options){
Expand Down Expand Up @@ -92,7 +90,7 @@ var Job = class Job{
//where_to_insert="next_top_level"
if (this.initial_instruction) {
//Instruction.Control.send_to_job.insert_sent_from_job(this, sent_from_job)
Job.insert_instruction_at_location(this.initial_instruction, {job: this, offset: "program_counter"})
Job.insert_instruction(this.initial_instruction, {job: this, offset: "program_counter"})
}
const added_items_initial_length =
this.added_items_count = new Array(this.program_counter) //This array parallels and should be the same length as the run items on the do_list.
Expand Down Expand Up @@ -641,62 +639,18 @@ Job.prototype.do_next_item = function(){ //user calls this when they want the jo
this.sent_from_job_instruction_queue = []
this.set_up_next_do(0)
}
else if (Array.isArray(cur_do_item) && (cur_do_item.length == 0)){ //nothing to do, just skip it.
this.set_up_next_do(1)
}
else if (Instruction.is_control_instruction(cur_do_item)){
cur_do_item.do_item(this)
}
else if (Instruction.is_instruction_array(cur_do_item)){
this.wait_until_instruction_id_has_run = this.program_counter
this.send(cur_do_item)
}
/* for (var i = 0; i <= this.max_contiguous_instructions; i++){
if(i > 0) {this.program_counter += 1}
if (i == this.max_contiguous_instructions){
this.stop_for_reason("error", "Job: " + this.name + " has " + this.max_contiguous_instructions +
" instructions on the do list.<br/>" +
"That's too many. You might have an infinite loop.<br/>" +
"If you legitimately put that many instruction in one fell swoop,<br/>" +
"that prevents this job from getting proper feedback from Dexter.")
break;
}
else if(this.program_counter > this.do_list.length){ shouldnt("in do_next_item, instruction_array processing, pc is > doList.length")}
else if(this.program_counter === this.do_list.length){ //turn off heartbeat, but don't close socket until we've waited for the final instruction to be done
//this will not hit on the first iteration of this for loop,
//because this case would have been caught above.
this.program_counter -= 1 //LET Dexter.robot_done_with_instruction increment the PC and let the top of do_next_item
//catch that we're done and set the reason.
this.wait_until_instruction_id_has_run = this.program_counter
//even though we've sent out all the items on the do list, don't quit
//until the last sent item is confirmed done and robot_done_with_instruction calls
//set_up_next_do
break;
}
else {
var cur_do_item = this.do_list[this.program_counter] //for the first of a seq of instruction arrays, we end up retriveing it twice from the to do list but for non first, we need this each loop iteration
if (Instruction.is_instruction_array(cur_do_item)){ //first one will get this check twice (first is above) but that's ok
if ("gz".indexOf(cur_do_item[0]) != -1){
this.wait_until_instruction_id_has_run = this.program_counter
//this.set_up_next_do(1) //don't want to run this instruction again
this.send(cur_do_item)
break;
}
else {
this.send(cur_do_item)
}
}
else {//got non array so we finished the continuous arrays so done with do_next_item
//we just put out a list of instructions so wait until they're run before
//running any more do_list items
//this will not hit the first iteration
this.program_counter -= 1 //LET Dexter.robot_done_with_instruction increment the PC
this.wait_until_instruction_id_has_run = this.program_counter
break;
}
}
}
} */
else if (Array.isArray(cur_do_item)){
this.handle_function_call_or_gen_next_result(cur_do_item, cur_do_item)
//note that a user normally wouldn't directly put an array on the do_list,
//but Job.insert_instruction very likely would to put > 1 instruction on
}
else if (is_iterator(cur_do_item)){ //must be before "function" because an iterator is also of type "function".
var next_obj = cur_do_item.next()
var do_items = next_obj.value
Expand Down Expand Up @@ -1191,7 +1145,21 @@ Job.prototype.instruction_location_to_id = function(instruction_location, starti
else if (inst_loc == "before_program_counter") { return job_instance.program_counter - 1 }
else if (inst_loc == "after_program_counter") { return job_instance.program_counter + 1 }
else if (inst_loc == "end") { return job_instance.do_list.length } //bad for go_to but ok for insert instruction, ie a new last instruction
else if (inst_loc == "next_top_level") { return "next_top_level" } //used only by insert_instruction_at_location
else if (inst_loc == "next_top_level") { return "next_top_level" } //used only by insert_instruction
else if (inst_loc == "highest_completed_instruction") {
const hci = job_instance.highest_completed_instruction_id
if(!hci || (hci <= 0)) { return 0 }
else { return hci }
}
else if (inst_loc == "highest_completed_instruction_or_zero") {
const hci = job_instance.highest_completed_instruction_id
if(!hci || (hci <= 0) || (hci >= (this.do_list.length - 1))) { return 0 }
//for the last cause above: if we completed the job the last time through, then start over again at zero
else { return hci } //else we are resuming at
//the highest completed instruction. But beware, you *might* not want
//to do that instruction twice, in which case the instruction_location should be
// ["zero_or_highest_completed_instruction", 1]
}
else { // a label or a sync_point name search pc, then after, then before pc
if (starting_id == null) { starting_id = this.program_counter }
if (process == "forward_then_backward") { return job_instance.ilti_forward_then_backward(inst_loc, starting_id, orig_instruction_location) }
Expand Down Expand Up @@ -1311,7 +1279,7 @@ Job.prototype.ilti_backward = function(inst_loc, starting_id){
"<br/>in the original_instruction_location: " + orig_instruction_location)
}

Job.insert_instruction_at_location = function(instruction, location){
Job.insert_instruction = function(instruction, location){
const the_job = Job.job_of_instruction_location(location)
if (the_job){
const index = the_job.instruction_location_to_id(location)
Expand All @@ -1321,7 +1289,7 @@ Job.insert_instruction_at_location = function(instruction, location){
else { the_job.do_list.splice(index, 0, instruction) }
}
else {
dde_error("insert_instruction_at_location passed location: " + insert_instruction_at_location +
dde_error("insert_instruction passed location: " + insert_instruction +
" which doesn't specify a job. Location should be an array with" +
"a first element of a literal object of {job:'some-job'}")
}
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "electron-dde",
"productName": "DDE",
"version": "1.0.3",
"release_date": "Mar 12, 2017",
"name": "dexter_dev_env",
"productName": "dexter_dev_env",
"version": "1.0.4",
"release_date": "Mar 16, 2017",
"description": "Dexter Development Environment",
"author": "Fry",
"license": "GPL-3.0",
Expand Down
Loading

0 comments on commit 80e866f

Please sign in to comment.