Compare commits

...

96 Commits

Author SHA1 Message Date
Matt McWilliams c5e66a6f40 Merge pull request 'Merge in 9 months of work on capper branch' (#71) from capper into main
Reviewed-on: #71
2023-02-19 00:28:45 -05:00
Matt McWilliams cff558ef9a Add 15mm to mount void for camera bolt 2023-02-12 14:14:03 -05:00
Matt McWilliams 325837d93e Adjustment to allow space on the right side 2023-02-12 14:10:44 -05:00
Matt McWilliams 135540b261 Remove some material for the rails 2023-02-03 20:08:18 -05:00
Matt McWilliams 49464cd25a Finished the design of the lens assembly base z attachment 2023-02-02 19:48:30 -05:00
Matt McWilliams d0fe54b429 Add m5 nut to the common lib 2023-02-02 19:48:08 -05:00
Matt McWilliams 2dce6f4b08 Merge branch 'capper' of git.sixteenmillimeter.com:16mm/mcopy into capper 2023-01-31 11:52:13 -05:00
Matt McWilliams 99794d04c2 jk assembly and arri-s wip 2023-01-31 11:52:10 -05:00
Matt McWilliams cc06655cd6 Update debug 2023-01-23 00:28:26 -05:00
Matt McWilliams ab6f517d27 Rails work 2023-01-17 12:04:03 -05:00
Matt McWilliams 682167db48 Add new commands for takeup forward and takeup backward 2023-01-15 10:09:55 -05:00
Matt McWilliams f127dc1128 Merge remote-tracking branch 'origin/capper' into capper 2023-01-14 15:26:07 -05:00
Matt McWilliams 0b816ae8e1 Adjust the position of the Z axis, move the linear bearing up and down to prevent binding on motion 2023-01-14 15:25:53 -05:00
Matt McWilliams c600fea4e1 Start rails concept 2023-01-12 19:26:05 -05:00
Matt McWilliams 92067bdbef Add top part to assembly 2023-01-11 19:17:15 -05:00
Matt McWilliams c181e003a3 First draft of base 2023-01-07 18:43:59 -05:00
Matt McWilliams 597137670d Merge base work with knob changes 2023-01-06 10:31:25 -05:00
Matt McWilliams 3036aebbc4 Knob and collar work 2023-01-06 09:18:03 -05:00
Matt McWilliams cbe6477af2 Improvements to bearing and Tnut size 2023-01-05 17:35:25 -05:00
Matthew McWilliams c2546d2bc5 Add m3 nuts and bolts to threaded z movement 2023-01-05 14:40:25 -05:00
Matt McWilliams 46be1bfd3b Assembly work. Adjusted design to simplify placement of 2 linear bearings 2023-01-04 23:11:48 -05:00
Matt McWilliams 1029885047 Update threaded Z, still needs m3 bolts 2023-01-04 18:26:22 -05:00
Matt McWilliams 164bde8cce All arri s mount and jk lens assembly work. need to do some branch cleanup on this project and tackle capper issues for merge of this branch. 2023-01-03 21:16:19 -05:00
Matt McWilliams 41504caac9 Increase the bolt size on the bellows board 2023-01-02 17:11:44 -05:00
Matt McWilliams 9b34b4e026 Adjust the height of the mount (-14.5mm) and make bolt voids larger 2023-01-02 14:33:16 -05:00
Matt McWilliams 95612c1d18 Add m3 nuts 2023-01-02 14:30:54 -05:00
Matt McWilliams 0829ec9081 Use a variable 2023-01-02 13:53:41 -05:00
Matt McWilliams ef0d246901 Increase the inner diameter of the bellows board to allow the threads to pass through cleanly and be held in place by the screw 2023-01-02 13:53:30 -05:00
Matt McWilliams 622a8a7c42 Add first concept bellows board 2023-01-01 11:43:30 -05:00
Matt McWilliams 925659ba4b Create an Arri S mount for the JK rails 2023-01-01 11:43:21 -05:00
Matt McWilliams 20c9287ac2 Work on concept JK lens assembly 2022-12-24 17:36:25 -05:00
Matt McWilliams 8aaa2b8940 Add a concept JK lens assembly 2022-12-24 01:55:11 -05:00
Matt McWilliams 30bd35e21d Add an M4 nut to the common OpenSCAD lib 2022-12-24 01:54:57 -05:00
Matthew McWilliams 0c2e39f0b2 Arri bellows work 2022-12-23 23:01:37 -05:00
Matt McWilliams cbd7001228 Save work on the JK99 shield. 2022-11-13 17:35:18 -05:00
Matt McWilliams dec96ec9be Use variable in stepper declaration 2022-11-11 15:47:58 -05:00
Matt McWilliams 3942cd05be Declare stepsPerRevolution so change is explicit when that happens 2022-11-11 15:47:43 -05:00
Matt McWilliams ee1e9c9feb Stepper firmware is working. Needed extra tape around coupling connector to add friction to connection and now it keeps. 2022-11-04 19:37:11 -04:00
Matt McWilliams fcb77232ec Create the driveCoupling module for the stepper motor design 2022-10-30 12:14:25 -04:00
Matt McWilliams 1fcbec7466 Work on stepper motor design and software. Motor still moves more slowly than it should but will investigate multiple factors leading to this result 2022-10-28 19:46:02 -04:00
Matt McWilliams 98f2c7a24a Pausing work on arri_s_DC firmware because hardware is less than ideal. Too much play in the motor position to trust right now. Steppers better approach. 2022-10-28 11:28:30 -04:00
Matt McWilliams 787e6ed06e Add a concept arri_s camera controller firmware. Using class-based approach as an experiment in Arduino code structure. 2022-10-28 07:50:30 -04:00
Matt McWilliams bb5b7c7897 Add divot to the drive coupling 2022-10-28 07:44:19 -04:00
Matt McWilliams 42b3aa767d Allow for even more space for microswritch 2022-10-28 01:32:58 -04:00
Matt McWilliams b20a6084e6 Allow for more space for the microswitch 2022-10-27 18:10:13 -04:00
Matthew McWilliams d9a8576701 Adjust size of drive coupling for the DC connector 2022-10-21 16:05:56 -04:00
Matthew McWilliams 69273d2a1c Increase scale of motor shaft void by 5% 2022-10-21 15:26:17 -04:00
Matthew McWilliams 755ea757f7 Add set screw for bearing and counter sink bolt caps for other cap m3s 2022-10-21 15:24:21 -04:00
Matt McWilliams 81fc54af8d DC motor design has all components designed, need to print, test and adjust. 2022-10-19 06:38:56 -04:00
Matt McWilliams 4281ca4390 Work on Arri-S DC motor 2022-10-16 19:03:02 -04:00
Matt McWilliams 3419172535 Arri-S work 2022-10-15 00:13:05 -04:00
Matt McWilliams 206c266b08 Added Arri-S motor and cap measurements as taken 10/8/2022 2022-10-09 11:22:12 -04:00
Matthew McWilliams 5026cf869f Arri-S work 2022-10-07 19:47:56 -04:00
Matthew McWilliams d5ecd9e057 Improve capper documentation 2022-09-16 09:45:19 -04:00
Matthew McWilliams 72b5077356 Restructure includes and type definition files so that mscript runs 2022-08-07 22:18:58 -04:00
Matthew McWilliams 6601c030f7 Refactor mscript GUI code into Typescript 2022-08-07 22:10:53 -04:00
Matthew McWilliams 3ec1373f08 Caught a possible ancient bug in the loop logic for calculating state of camera and projector backwards movements. 2022-08-07 17:23:06 -04:00
Matt McWilliams b29478cb58 Increment build patch version 2022-08-04 10:57:36 -04:00
Matt McWilliams fe61e63e76 Add secondary projector and camera commands to the mscript module 2022-08-04 10:52:00 -04:00
Matt McWilliams ee0ab663d7 Complete the alert feature. Have not created pause, but this could be done using the same alert object to prevent code duplication. 2022-08-03 09:02:47 -04:00
Matt McWilliams 1964d6002d Add mono logo as png, but might use svg instead. Render crashed PC. 2022-07-22 21:56:43 -04:00
Matt McWilliams f55b72044c Mcopy firmware with optional capper feature 2022-07-17 11:05:20 -04:00
Matt McWilliams 3f759f5678 Add the ability to detect a single capper device 2022-07-17 09:57:52 -04:00
Matt McWilliams 6582154ec6 Fix debug script and component 2022-07-17 09:56:03 -04:00
Matt McWilliams 9d0545aa4f All capper features in app, can shoot blank frames, can turn on capper independently and can schedule blank frames in the sequencer. Some cleanup may be needed but there are no noticeable regressions in the app. TODO: Finish all arduino scripts. 2022-07-15 18:11:26 -04:00
Matt McWilliams ea055d6e56 Capper case candidate 2022-07-13 23:04:00 -04:00
Matthew McWilliams bc48765b35 Start work on base 2022-07-13 18:16:43 -04:00
Matthew McWilliams 70c2c695f0 All capper work. Need to wrap all actions in the 'b' command and push functionality to a lower level to prevent unneeded complexity. 2022-07-13 15:21:26 -04:00
Matthew McWilliams 8ec5816364 Adjust settings page to support Processing input 2022-07-13 10:15:47 -04:00
Matthew McWilliams c33c6e24f6 Work on motor rod 2022-07-13 09:01:25 -04:00
Matt McWilliams b0ca15bd8d Merge branch 'capper' of git.sixteenmillimeter.com:16mm/mcopy into capper 2022-07-13 08:28:58 -04:00
Matt McWilliams 76799bd66d Capper work 2022-07-13 08:28:18 -04:00
Matthew McWilliams 18dbb72a54 Minor updates to comments 2022-07-06 14:42:53 -04:00
Matthew McWilliams c0ec81c0f9 Add Servo debug script 2022-07-06 14:42:16 -04:00
Matt McWilliams c3661d6ff1 Remove opto endstop logic, ready for hardware testing. 2022-06-28 08:58:31 -04:00
Matt McWilliams c0f056cd8d Re-render all STLs for capper, removing the opto endstop component (for now) 2022-06-28 08:38:11 -04:00
Matt McWilliams 2924efe39f Reduce the size of the void for the screw in the cap. 2022-06-28 08:34:29 -04:00
Matt McWilliams e275539fb0 Remove endstop completely and start rounding surfaces. 2022-06-22 07:45:01 -04:00
Matt McWilliams 4c13c54815 Updates to endstop mount design. Had incorrectly positioned voids for SMD chips on the endstop 2022-06-20 13:00:40 -04:00
Matt McWilliams 62a66f5f6d More mount work and start of endstop logic. Rebuilding the B&H projector unity. 2022-06-17 23:39:19 -04:00
Matt McWilliams 3a435933e3 Work on the opto endstop mount. This needs to be re-oriented before next print. 2022-06-16 00:29:31 -04:00
Matt McWilliams 78f7ac0e68 Mount work 2022-06-13 22:46:23 -04:00
Matt McWilliams 28dc19fc32 Work on endstop functionality 2022-06-13 22:46:13 -04:00
Matt McWilliams 585c47d6c7 Allow capper identifier in list of acceptable responses. 2022-06-13 08:08:42 -04:00
Matt McWilliams 04a0330327 All work on first draft of capper hardware 2022-06-12 22:26:03 -04:00
Matt McWilliams dae4e65aee Merge branch 'capper' of git.sixteenmillimeter.com:16mm/mcopy into capper 2022-06-12 13:37:52 -04:00
Matt McWilliams 129647b863 App work 2022-06-12 13:37:00 -04:00
Matt McWilliams 2f9201716a All capper work. Debug firmware for testing. STL of cap as printed. 2022-06-12 13:14:43 -04:00
Matt McWilliams f9d716552b Merge branch 'capper' of git.sixteenmillimeter.com:16mm/mcopy into capper 2022-06-11 16:06:25 -04:00
Matt McWilliams 818c8453ee Capper OpenSCAD work 2022-06-11 16:03:08 -04:00
Matthew McWilliams f7a3c52260 Silly typo: did not invoke Servo_init() and so servo was not initalizing 2022-06-10 13:19:38 -04:00
Matt McWilliams 9d3bf24627 Hardware ideas for capper mount and flag. Need to model servo and add places for endstops 2022-06-07 07:55:47 -04:00
Matt McWilliams c77201ef4e Add new commands and identifiers for the capper, start moving into capital characters 2022-06-07 07:55:26 -04:00
Matt McWilliams f585aa2a5a Upgrade electron 11 -> 19 (huge jump). Install new remote module to preserve legacy communication protocol. 2022-06-04 11:11:23 -04:00
Matt McWilliams 96e0ce6050 Merge branch 'capper' of git.sixteenmillimeter.com:16mm/mcopy into capper 2022-05-31 17:44:56 -04:00
Matt McWilliams c15c376a2f Start work on capper branch 2022-05-30 18:50:18 -04:00
120 changed files with 7989 additions and 3498 deletions

View File

@ -484,6 +484,9 @@ button:focus {
#sequence #projector_second_backward > div {
color: #bf2e39;
}
#sequence #black input[type=checkbox]:checked {
background: white;
}
#sequence input[type=checkbox] {
-webkit-appearance: none;
-moz-appearance: none;
@ -500,6 +503,10 @@ button:focus {
box-sizing: border-box;
cursor: pointer;
}
#sequence input[type=checkbox].disabled {
cursor: not-allowed;
border-color: #646464;
}
#sequence .L {
display: inline-block;
width: 35px;
@ -627,6 +634,11 @@ button:focus {
background: #AB1A25;
border-color: #AB1A25;
}
.cmd:active.capper,
.cmd.active.capper {
background: white;
color: #272b30;
}
.cmd:active i,
.cmd.active i {
color: #272b30;
@ -650,6 +662,9 @@ button:focus {
::-webkit-scrollbar-thumb:window-inactive {
background: rgba(0, 0, 0, 0.05);
}
#settings h4 {
margin-bottom: 1px;
}
#settings > div {
width: 300px;
margin: 0 auto;
@ -696,6 +711,9 @@ button:focus {
border-color: #DAE035;
color: #DAE035;
}
#settings input[type=text] {
width: 200px;
}
#settings button {
margin-top: -1px;
float: right;
@ -1134,19 +1152,23 @@ button:focus {
float: right;
}
.cam2,
.proj2 {
.proj2,
.black {
display: none;
}
.cam2 > *,
.proj2 > * {
.proj2 > *,
.black > * {
visibility: hidden;
}
.cam2.on,
.proj2.on {
.proj2.on,
.black.on {
display: block;
}
.cam2.on > *,
.proj2.on > * {
.proj2.on > *,
.black.on > * {
visibility: visible;
}
#overlay {

View File

@ -1,5 +1,5 @@
{
"version": "1.6.9",
"version": "1.7.1",
"ext_port": 1111,
"profiles": {
"mcopy": {
@ -15,8 +15,8 @@
"momentary": 0
},
"black": {
"before": 0,
"after": 0
"before": 100,
"after": 100
},
"light": false
},
@ -178,7 +178,13 @@
"cameras": "4",
"camera_projectors_identifier": "5",
"cameras_projector_identifier": "6",
"cameras_projectors_identifier": "7"
"cameras_projectors_identifier": "7",
"capper_identifier": "C",
"camera_capper_identifier": "8",
"camera_capper_projector_identifier": "9",
"camera_capper_projectors_identifier": "0",
"capper_on": "A",
"capper_off": "B"
}
}
}

View File

@ -46,6 +46,8 @@
<div id="projector_backward" class="row" y="1"></div>
<div id="projector_second_backward" class="row proj2" y="3"></div>
<div id="black" class="row black"></div>
<div id="light_set" class="row spacer"></div>
<div id="numbers" class="row"></div>
</div>
@ -60,6 +62,8 @@
<div><span>PROJ </span><i class="fa fa-minus"></i></div>
<div class="proj2"><span>PROJ2 </span><i class="fa fa-minus"></i></div>
<div class="black"><span>BLANK </span><i class="fa fa-times"></i></div>
<div class="spacer"><span>LIGHT</span></div>
</div>
</div>
@ -158,6 +162,20 @@
<i class="fa fa-step-backward"></i>
</button>
</div>
<div class="hide">
<button id="cmd_capper_on" onclick="cmd.capper_on();" class="cmd capper">
<i class="fa fa-times-circle"></i>
CAPPER ON
<i class="fa fa-eye"></i>
</button>
</div>
<div class="hide">
<button id="cmd_capper_off" onclick="cmd.capper_off();" class="cmd capper active">
<i class="fa fa-eye"></i>
CAPPER OFF
<i class="fa fa-eye"></i>
</button>
</div>
</div>
<div>
<div>

View File

@ -2474,8 +2474,9 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
!function(a,b){"object"==typeof exports?module.exports=b():"function"==typeof define&&define.amd?define(b):a.Spinner=b()}(this,function(){"use strict";function a(a,b){var c,d=document.createElement(a||"div");for(c in b)d[c]=b[c];return d}function b(a){for(var b=1,c=arguments.length;c>b;b++)a.appendChild(arguments[b]);return a}function c(a,b,c,d){var e=["opacity",b,~~(100*a),c,d].join("-"),f=.01+c/d*100,g=Math.max(1-(1-a)/b*(100-f),a),h=j.substring(0,j.indexOf("Animation")).toLowerCase(),i=h&&"-"+h+"-"||"";return l[e]||(m.insertRule("@"+i+"keyframes "+e+"{0%{opacity:"+g+"}"+f+"%{opacity:"+a+"}"+(f+.01)+"%{opacity:1}"+(f+b)%100+"%{opacity:"+a+"}100%{opacity:"+g+"}}",m.cssRules.length),l[e]=1),e}function d(a,b){var c,d,e=a.style;for(b=b.charAt(0).toUpperCase()+b.slice(1),d=0;d<k.length;d++)if(c=k[d]+b,void 0!==e[c])return c;return void 0!==e[b]?b:void 0}function e(a,b){for(var c in b)a.style[d(a,c)||c]=b[c];return a}function f(a){for(var b=1;b<arguments.length;b++){var c=arguments[b];for(var d in c)void 0===a[d]&&(a[d]=c[d])}return a}function g(a,b){return"string"==typeof a?a:a[b%a.length]}function h(a){this.opts=f(a||{},h.defaults,n)}function i(){function c(b,c){return a("<"+b+' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">',c)}m.addRule(".spin-vml","behavior:url(#default#VML)"),h.prototype.lines=function(a,d){function f(){return e(c("group",{coordsize:k+" "+k,coordorigin:-j+" "+-j}),{width:k,height:k})}function h(a,h,i){b(m,b(e(f(),{rotation:360/d.lines*a+"deg",left:~~h}),b(e(c("roundrect",{arcsize:d.corners}),{width:j,height:d.width,left:d.radius,top:-d.width>>1,filter:i}),c("fill",{color:g(d.color,a),opacity:d.opacity}),c("stroke",{opacity:0}))))}var i,j=d.length+d.width,k=2*j,l=2*-(d.width+d.length)+"px",m=e(f(),{position:"absolute",top:l,left:l});if(d.shadow)for(i=1;i<=d.lines;i++)h(i,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(i=1;i<=d.lines;i++)h(i);return b(a,m)},h.prototype.opacity=function(a,b,c,d){var e=a.firstChild;d=d.shadow&&d.lines||0,e&&b+d<e.childNodes.length&&(e=e.childNodes[b+d],e=e&&e.firstChild,e=e&&e.firstChild,e&&(e.opacity=c))}}var j,k=["webkit","Moz","ms","O"],l={},m=function(){var c=a("style",{type:"text/css"});return b(document.getElementsByTagName("head")[0],c),c.sheet||c.styleSheet}(),n={lines:12,length:7,width:5,radius:10,rotate:0,corners:1,color:"#000",direction:1,speed:1,trail:100,opacity:.25,fps:20,zIndex:2e9,className:"spinner",top:"50%",left:"50%",position:"absolute"};h.defaults={},f(h.prototype,{spin:function(b){this.stop();{var c=this,d=c.opts,f=c.el=e(a(0,{className:d.className}),{position:d.position,width:0,zIndex:d.zIndex});d.radius+d.length+d.width}if(e(f,{left:d.left,top:d.top}),b&&b.insertBefore(f,b.firstChild||null),f.setAttribute("role","progressbar"),c.lines(f,c.opts),!j){var g,h=0,i=(d.lines-1)*(1-d.direction)/2,k=d.fps,l=k/d.speed,m=(1-d.opacity)/(l*d.trail/100),n=l/d.lines;!function o(){h++;for(var a=0;a<d.lines;a++)g=Math.max(1-(h+(d.lines-a)*n)%l*m,d.opacity),c.opacity(f,a*d.direction+i,g,d);c.timeout=c.el&&setTimeout(o,~~(1e3/k))}()}return c},stop:function(){var a=this.el;return a&&(clearTimeout(this.timeout),a.parentNode&&a.parentNode.removeChild(a),this.el=void 0),this},lines:function(d,f){function h(b,c){return e(a(),{position:"absolute",width:f.length+f.width+"px",height:f.width+"px",background:b,boxShadow:c,transformOrigin:"left",transform:"rotate("+~~(360/f.lines*k+f.rotate)+"deg) translate("+f.radius+"px,0)",borderRadius:(f.corners*f.width>>1)+"px"})}for(var i,k=0,l=(f.lines-1)*(1-f.direction)/2;k<f.lines;k++)i=e(a(),{position:"absolute",top:1+~(f.width/2)+"px",transform:f.hwaccel?"translate3d(0,0,0)":"",opacity:f.opacity,animation:j&&c(f.opacity,f.trail,l+k*f.direction,f.lines)+" "+1/f.speed+"s linear infinite"}),f.shadow&&b(i,e(h("#000","0 0 4px #000"),{top:"2px"})),b(d,b(i,h(g(f.color,k),"0 0 1px rgba(0,0,0,.1)")));return d},opacity:function(a,b,c){b<a.childNodes.length&&(a.childNodes[b].style.opacity=c)}});var o=e(a("group"),{behavior:"url(#default#VML)"});return!d(o,"transform")&&o.adj?i():j=d(o,"animation"),h});
const mcopy = {};
const { remote, ipcRenderer } = require('electron');
const dialog = require('electron').remote.dialog;
const remote = require('@electron/remote');
const { ipcRenderer } = require('electron');
const { dialog } = remote;
const notifier = require('node-notifier');
const fs = require('fs');
const uuid = require('uuid').v4;
@ -2495,8 +2496,10 @@ const cmd = require('./lib/ui/cmd.js');
const devices = require('./lib/ui/devices.js');
const filmout = require('./lib/ui/filmout.js');
const mse = require('./lib/ui/mscript.js');
const capper = require('./lib/ui/capper.js');
const Mscript = require('./lib/mscript');
const { delay } = require('./lib/delay');
const alertObj = require('./lib/ui/alert.js');
let log;
@ -2524,4 +2527,6 @@ async function init () {
proj.init();
cam.init();
seq.init();
capper.init();
alertObj.init();
};

View File

@ -175,7 +175,8 @@
}
.cam2,
.proj2{
.proj2,
.black{
display : none;
> * {
visibility: hidden;

View File

@ -42,6 +42,10 @@
background: @BACKWARD;
border-color: @BACKWARD;
}
&.capper{
background: white;
color: @BG;
}
i{
color: @BG;
}

View File

@ -126,6 +126,13 @@
color: @BACKWARD + @SECOND;
}
}
#black{
input[type=checkbox]{
&:checked{
background: white;
}
}
}
input[type=checkbox]{
-webkit-appearance: none;
-moz-appearance: none;
@ -141,6 +148,10 @@
display: inline-block;
box-sizing: border-box;
cursor: pointer;
&.disabled{
cursor: not-allowed;
border-color: rgb(100, 100, 100);
}
}
.L{
display: inline-block;

View File

@ -1,4 +1,7 @@
#settings{
h4{
margin-bottom: 1px;
}
> div{
width: 300px;
margin: 0 auto;
@ -6,7 +9,8 @@
> div > div{
width: 360px;
}
input[type=text], select{
input[type=text],
select{
.button();
display: inline-block;
padding: 6px 12px;
@ -17,6 +21,9 @@
color: @SELECTED;
}
}
input[type=text]{
width: 200px;
}
button{
margin-top: -1px;
float: right;

1
app/lib/alert/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

58
app/lib/alert/index.js Normal file
View File

@ -0,0 +1,58 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
/* class representing alert functionality */
class Alert {
constructor(ui) {
this.id = 'alert';
this.cb = null;
this.ui = ui;
this.init();
}
/**
*
**/
async init() {
const Log = require('log');
this.log = await Log({ label: this.id });
this.ipc = require('electron').ipcMain;
this.listen();
}
/**
*
**/
listen() {
this.ipc.on(this.id, this.listener.bind(this));
}
/**
*
**/
async listener(event, arg) {
if (this.cb !== null) {
try {
await this.cb(arg.state, arg.id);
}
catch (err) {
this.log.error(err);
}
}
event.returnValue = true;
}
/**
*
**/
async start(cmd) {
const start = +new Date();
const msg = (cmd + '').replace('ALERT', '').replace('Alert', '').replace('alert', '').trim();
this.ui.send(this.id, { msg });
return new Promise(function (resolve, reject) {
this.cb = function () {
const ms = (+new Date()) - start;
return resolve(ms);
};
}.bind(this));
}
}
module.exports = function (ui) {
return new Alert(ui);
};
//# sourceMappingURL=index.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/alert/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAIb,4CAA4C;AAE5C,MAAM,KAAK;IAOV,YAAc,EAAQ;QAJd,OAAE,GAAY,OAAO,CAAA;QACrB,OAAE,GAAc,IAAI,CAAA;QAI3B,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;QACZ,IAAI,CAAC,IAAI,EAAE,CAAA;IACZ,CAAC;IAED;;QAEI;IACI,KAAK,CAAC,IAAI;QACjB,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;QAC1B,IAAI,CAAC,GAAG,GAAG,MAAM,GAAG,CAAC,EAAE,KAAK,EAAG,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;QACzC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO,CAAA;QACtC,IAAI,CAAC,MAAM,EAAE,CAAA;IACd,CAAC;IAED;;QAEI;IACI,MAAM;QACb,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC/C,CAAC;IAED;;QAEI;IACI,KAAK,CAAC,QAAQ,CAAE,KAAW,EAAE,GAAS;QAC7C,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE;YACrB,IAAI;gBACH,MAAM,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;aAChC;YAAC,OAAO,GAAG,EAAE;gBACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;aACnB;SACD;QACD,KAAK,CAAC,WAAW,GAAG,IAAI,CAAA;IACzB,CAAC;IAED;;QAEI;IACG,KAAK,CAAC,KAAK,CAAE,GAAY;QAC/B,MAAM,KAAK,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAY,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;QACrG,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAA;QAC9B,OAAO,IAAI,OAAO,CAAC,UAAU,OAAkB,EAAE,MAAiB;YACjE,IAAI,CAAC,EAAE,GAAG;gBACT,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC;gBACjC,OAAO,OAAO,CAAC,EAAE,CAAC,CAAC;YACpB,CAAC,CAAA;QACF,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACf,CAAC;CACD;AAED,MAAM,CAAC,OAAO,GAAG,UAAU,EAAQ;IAClC,OAAO,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC;AACtB,CAAC,CAAA"}

1
app/lib/arduino/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

View File

@ -2,10 +2,10 @@
Object.defineProperty(exports, "__esModule", { value: true });
//import Log = require('log');
const delay_1 = require("delay");
const SerialPort = require('serialport');
const Readline = SerialPort.parsers.Readline;
const { SerialPort } = require('serialport');
const { ReadlineParser } = require('@serialport/parser-readline');
const exec = require('child_process').exec;
const parser = new Readline('');
const parser = new ReadlineParser({});
const newlineRe = new RegExp('\n', 'g');
const returnRe = new RegExp('\r', 'g');
let eventEmitter;
@ -100,7 +100,6 @@ class Arduino {
//console.error(err)
return reject(err);
}
//
});
});
}
@ -190,7 +189,8 @@ class Arduino {
let connectSuccess;
this.path[serial] = device;
this.alias[serial] = device;
this.serial[device] = new SerialPort(this.path[serial], {
this.serial[device] = new SerialPort({
path: this.path[serial],
autoOpen: false,
baudRate: cfg.arduino.baud,
parser: parser
@ -241,7 +241,11 @@ class Arduino {
|| data === cfg.arduino.cmd.camera_second_forward
|| data === cfg.arduino.cmd.camera_second_backward
|| data === cfg.arduino.cmd.camera_second
|| data === cfg.arduino.cmd.cameras) {
|| data === cfg.arduino.cmd.cameras
|| data === cfg.arduino.cmd.capper_identifier
|| data === cfg.arduino.cmd.camera_capper_identifier
|| data === cfg.arduino.cmd.camera_capper_projector_identifier
|| data === cfg.arduino.cmd.camera_capper_projectors_identifier) {
this.confirmExec(null, data);
this.confirmExec = {};
}
@ -313,11 +317,24 @@ class Arduino {
else if (data === cfg.arduino.cmd.cameras_projectors_identifier) {
type = 'camera,camera_second,projector,projector_second';
}
else if (data === cfg.arduino.cmd.capper_identifier) {
type = 'capper';
}
else if (data === cfg.arduino.cmd.camera_capper_identifier) {
type = 'camera,capper';
}
else if (data === cfg.arduino.cmd.camera_capper_projector_identifier) {
type = 'camera,capper,projector';
}
else if (data === cfg.arduino.cmd.camera_capper_projectors_identifier) {
type = 'camera,capper,projector,projector_second';
}
return resolve(type);
};
await delay_1.delay(cfg.arduino.serialDelay);
try {
writeSuccess = await this.sendAsync(device, cfg.arduino.cmd.mcopy_identifier);
this.log.info(writeSuccess);
}
catch (e) {
return reject(e);
@ -343,7 +360,9 @@ class Arduino {
write: async function (cmd, cb) {
const t = {
c: cfg.arduino.cam.time + cfg.arduino.cam.delay,
p: cfg.arduino.proj.time + cfg.arduino.proj.delay
p: cfg.arduino.proj.time + cfg.arduino.proj.delay,
A: 180,
B: 180
};
let timeout = t[cmd];
if (typeof timeout === 'undefined')

File diff suppressed because one or more lines are too long

1
app/lib/cam/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

View File

@ -10,7 +10,8 @@ class Camera {
constructor(arduino, cfg, ui, filmout, second = false) {
this.state = {
pos: 0,
dir: true
dir: true,
capepr: false
};
this.arduino = null;
this.intval = null;
@ -80,6 +81,27 @@ class Camera {
}
return await this.end(cmd, id, ms);
}
/**
*
**/
async cap(state, id) {
let cmd;
let ms;
if (state) {
cmd = this.cfg.arduino.cmd[`${this.id}_forward`];
}
else {
cmd = this.cfg.arduino.cmd[`${this.id}_backward`];
}
this.state.capper = state;
try {
ms = await this.arduino.send(this.id, cmd);
}
catch (err) {
this.log.error(err);
}
return await this.end(cmd, id, ms);
}
/**
*
**/
@ -202,6 +224,14 @@ class Camera {
else if (typeof arg.val !== 'undefined') {
this.state.pos = arg.val;
}
else if (typeof arg.capper !== 'undefined') {
try {
await this.cap(arg.capper, arg.id);
}
catch (err) {
this.log.error(err);
}
}
event.returnValue = true;
}
/**

File diff suppressed because one or more lines are too long

1
app/lib/capper/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

89
app/lib/capper/index.js Normal file
View File

@ -0,0 +1,89 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
/** class representing capper functions **/
class Capper {
/**
*
**/
constructor(arduino, cfg, ui, filmout) {
this.state = {
capper: false
};
this.arduino = null;
this.id = 'capper';
this.arduino = arduino;
this.cfg = cfg;
this.ui = ui;
this.filmout = filmout;
this.init();
}
/**
*
**/
async init() {
const Log = require('log');
this.log = await Log({ label: this.id });
this.ipc = require('electron').ipcMain;
this.listen();
}
/**
*
**/
listen() {
this.ipc.on(this.id, this.listener.bind(this));
}
/**
*
**/
async capper(state, id) {
let cmd;
let ms;
if (state) {
cmd = this.cfg.arduino.cmd[`${this.id}_on`];
}
else {
cmd = this.cfg.arduino.cmd[`${this.id}_off`];
}
this.state.capper = state;
try {
ms = await this.arduino.send(this.id, cmd);
}
catch (err) {
this.log.error(err);
}
return await this.end(cmd, id, ms);
}
/**
*
**/
async listener(event, arg) {
if (typeof arg.state !== 'undefined') {
try {
await this.capper(arg.state, arg.id);
}
catch (err) {
this.log.error(err);
}
}
event.returnValue = true;
}
/**
*
**/
async end(cmd, id, ms) {
let message = '';
if (cmd === this.cfg.arduino.cmd.capper_on) {
message = 'Capper set to ON';
}
else if (cmd === this.cfg.arduino.cmd.capper_off) {
message = 'Capper set to OFF';
}
message += ` ${ms}ms`;
this.log.info(message);
this.ui.send(this.id, { cmd: cmd, id: id, ms: ms });
}
}
module.exports = function (arduino, cfg, ui, filmout) {
return new Capper(arduino, cfg, ui, filmout);
};
//# sourceMappingURL=index.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/capper/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAMb,2CAA2C;AAE3C,MAAM,MAAM;IAWX;;QAEI;IACJ,YAAa,OAAiB,EAAE,GAAS,EAAE,EAAQ,EAAE,OAAa;QAb1D,UAAK,GAAS;YACrB,MAAM,EAAG,KAAK;SACd,CAAC;QACM,YAAO,GAAa,IAAI,CAAC;QAMzB,OAAE,GAAY,QAAQ,CAAC;QAK9B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,IAAI,EAAE,CAAC;IACb,CAAC;IAED;;QAEI;IACI,KAAK,CAAC,IAAI;QACjB,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,CAAC,GAAG,GAAG,MAAM,GAAG,CAAC,EAAE,KAAK,EAAG,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC;QACvC,IAAI,CAAC,MAAM,EAAE,CAAC;IACf,CAAC;IAED;;QAEI;IACI,MAAM;QACb,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;IAED;;QAEI;IACI,KAAK,CAAC,MAAM,CAAE,KAAe,EAAE,EAAW;QACjD,IAAI,GAAY,CAAC;QACjB,IAAI,EAAW,CAAC;QAEhB,IAAI,KAAK,EAAE;YACV,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;SAC5C;aAAM;YACN,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;SAC7C;QAED,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC;QAE1B,IAAI;YACH,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;SAC3C;QAAC,OAAO,GAAG,EAAE;YACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SACpB;QAED,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACpC,CAAC;IAED;;QAEI;IACI,KAAK,CAAC,QAAQ,CAAE,KAAW,EAAE,GAAS;QAC7C,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,WAAW,EAAE;YACrC,IAAI;gBACH,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;aACpC;YAAC,OAAO,GAAG,EAAE;gBACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;aACnB;SACD;QACD,KAAK,CAAC,WAAW,GAAG,IAAI,CAAA;IACzB,CAAC;IAED;;QAEI;IACI,KAAK,CAAC,GAAG,CAAE,GAAY,EAAE,EAAW,EAAE,EAAW;QACxD,IAAI,OAAO,GAAG,EAAE,CAAC;QAEjB,IAAI,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE;YAC3C,OAAO,GAAG,kBAAkB,CAAC;SAC7B;aAAM,IAAI,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE;YACnD,OAAO,GAAG,mBAAmB,CAAC;SAC9B;QAED,OAAO,IAAI,IAAI,EAAE,IAAI,CAAA;QAErB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAC,CAAC,CAAC;IACpD,CAAC;CACD;AAED,MAAM,CAAC,OAAO,GAAG,UAAU,OAAiB,EAAE,GAAS,EAAE,EAAQ,EAAE,OAAY;IAC9E,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC,CAAA"}

1
app/lib/cmd/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

View File

@ -12,17 +12,20 @@ class Commands {
* @param {object} cam Camera 1
* @param {object} light Light source
* @param {object} cam2 (optional) Camera 2
* @param {object} proj2 {optional} Projector 2
* @param {object} proj2 (optional) Projector 2
**/
constructor(cfg, proj, cam, light, cam2 = null, proj2 = null) {
constructor(cfg, proj, cam, light, alert, cam2 = null, proj2 = null, capper = null) {
this.cfg = cfg;
this.proj = proj;
this.cam = cam;
this.light = light;
if (cam2)
this.alertObj = alert;
if (cam2 !== null)
this.cam2 = cam2;
if (proj2)
if (proj2 !== null)
this.proj2 = proj2;
if (capper !== null)
this.capper = capper;
this.ipc = require('electron').ipcMain;
}
/**
@ -68,13 +71,14 @@ class Commands {
/**
* Move the camera one frame forward
*
* @param {array} rgb Color to set light for frame
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
async camera_forward(rgb = [255, 255, 255]) {
async camera_forward() {
const id = uuid_1.v4();
const off = [0, 0, 0];
let rgb = [255, 255, 255];
let ms;
try {
if (!this.cam.state.dir) {
@ -101,18 +105,25 @@ class Commands {
async black_forward() {
const id = uuid_1.v4();
const off = [0, 0, 0];
let ms;
let ms = 0;
try {
if (!this.cam.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.cam.set(true);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
if (this.capper) {
ms += await this.capper.capper(true, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.light.set(off, id); //make sure set to off
await delay_1.delay(this.cfg.arduino.serialDelay);
ms = await this.cam.move();
ms += await this.cam.move();
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.light.set(off, id);
if (this.capper) {
ms += await this.capper.capper(false, id);
}
}
catch (err) {
throw err;
@ -122,13 +133,14 @@ class Commands {
/**
* Move the camera one frame backward
*
* @param {array} rgb Color to set light for frame
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
async camera_backward(rgb = [255, 255, 255]) {
async camera_backward() {
const id = uuid_1.v4();
const off = [0, 0, 0];
let rgb = [255, 255, 255];
let ms;
try {
if (this.cam.state.dir) {
@ -155,18 +167,24 @@ class Commands {
async black_backward() {
const id = uuid_1.v4();
const off = [0, 0, 0];
let ms;
let ms = 0;
try {
if (this.cam.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.cam.set(false);
}
if (this.capper) {
ms += await this.capper.capper(true, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.light.set(off, id); //make sure set to off
await delay_1.delay(this.cfg.arduino.serialDelay);
ms = await this.cam.move();
ms += await this.cam.move();
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.light.set(off, id);
if (this.capper) {
ms += await this.capper.capper(false, id);
}
}
catch (err) {
throw err;
@ -176,13 +194,14 @@ class Commands {
/**
* Move the second camera one frame forward
*
* @param {array} rgb Color to set light for frame
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
async camera_second_forward(rgb = [255, 255, 255]) {
async camera_second_forward() {
const id = uuid_1.v4();
const off = [0, 0, 0];
let rgb = [255, 255, 255];
let ms;
try {
if (!this.cam2.state.dir) {
@ -204,13 +223,14 @@ class Commands {
/**
* Move the second camera one frame backward
*
* @param {array} rgb Color to set light for frame
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
async camera_second_backward(rgb = [255, 255, 255]) {
async camera_second_backward() {
const id = uuid_1.v4();
const off = [0, 0, 0];
let rgb = [255, 255, 255];
let ms;
try {
if (this.cam2.state.dir) {
@ -232,13 +252,14 @@ class Commands {
/**
* Move the both cameras one frame forward
*
* @param {array} rgb Color to set light for frame
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
async cameras_forward(rgb = [255, 255, 255]) {
async cameras_forward() {
const id = uuid_1.v4();
const off = [0, 0, 0];
let rgb = [255, 255, 255];
let both;
let ms;
try {
@ -273,13 +294,14 @@ class Commands {
/**
* Move the both cameras one frame backward
*
* @param {array} rgb Color to set light for frame
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
async cameras_backward(rgb = [255, 255, 255]) {
async cameras_backward() {
const id = uuid_1.v4();
const off = [0, 0, 0];
let rgb = [255, 255, 255];
let both;
let ms;
try {
@ -314,13 +336,14 @@ class Commands {
/**
* Move first camera one frame forward and rewind secondary camera one frame backward
*
* @param {array} rgb Color to set light for frames
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
async camera_forward_camera_second_backward(rgb = [255, 255, 255]) {
async camera_forward_camera_second_backward() {
const id = uuid_1.v4();
const off = [0, 0, 0];
let rgb = [255, 255, 255];
let both;
let ms;
try {
@ -355,13 +378,14 @@ class Commands {
/**
* Rewind first camera one frame backward and move secondary camera one frame forward
*
* @param {array} rgb Color to set light for frame
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
async camera_backward_camera_second_forward(rgb = [255, 255, 255]) {
async camera_backward_camera_second_forward() {
const id = uuid_1.v4();
const off = [0, 0, 0];
let rgb = [255, 255, 255];
let both;
let ms;
try {
@ -570,8 +594,23 @@ class Commands {
}
return ms;
}
/**
* Throws an alert to pause a sequence
*
* @returns {integer} Length of action in ms
**/
async alert(cmd) {
let ms;
try {
ms = await this.alertObj.start(cmd.light); //change this meta
}
catch (err) {
throw err;
}
return ms;
}
}
module.exports = function (cfg, proj, cam, light, cam2, proj2) {
return new Commands(cfg, proj, cam, light, cam2, proj2);
module.exports = function (cfg, proj, cam, light, alert, cam2, proj2, capper) {
return new Commands(cfg, proj, cam, light, alert, cam2, proj2, capper);
};
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

0
app/lib/delay/index.d.ts vendored Normal file
View File

1
app/lib/devices/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

View File

@ -170,6 +170,22 @@ class Devices {
this.log.info('Connected to fake LIGHT device', 'SERIAL', true, true);
return true;
}
/**
*
**/
async fakeCapper() {
this.connected.capper = '/dev/fake';
try {
await this.arduino.fakeConnect('capper');
}
catch (err) {
console.error(err);
this.log.error(`Error connecting to fake CAPPER device`, 'SERIAL', true, true);
return false;
}
this.log.info('Connected to fake CAPPER device', 'SERIAL', true, true);
return true;
}
/**
*
**/
@ -302,7 +318,7 @@ class Devices {
return false;
}
}
else if ('camera,projector,projector_second') {
else if (type === 'camera,projector,projector_second') {
this.connected.camera = device;
this.connected.projector = device;
this.connected.projector_second = device;
@ -316,7 +332,7 @@ class Devices {
return false;
}
}
else if ('camera,camera_second,projector') {
else if (type === 'camera,camera_second,projector') {
this.connected.camera = device;
this.connected.camera_second = device;
this.connected.projector = device;
@ -330,7 +346,7 @@ class Devices {
return false;
}
}
else if ('camera,camera_second,projector,projector_second') {
else if (type === 'camera,camera_second,projector,projector_second') {
this.connected.camera = device;
this.connected.camera_second = device;
this.connected.projector = device;
@ -346,6 +362,58 @@ class Devices {
return false;
}
}
else if (type === 'capper') {
this.connected.capper = device;
try {
connectSuccess = await this.arduino.connect('capper', device, false);
}
catch (err) {
this.log.error('Error connecting capper', err);
return false;
}
}
else if (type === 'camera,capper') {
this.connected.camera = device;
this.connected.capper = device;
this.arduino.aliasSerial('capper', device);
try {
connectSuccess = await this.arduino.connect('camera', device, false);
}
catch (err) {
this.log.error('Error connecting to camera and capper', err);
return false;
}
}
else if (type === 'camera,capper,projector') {
this.connected.camera = device;
this.connected.capper = device;
this.connected.projector = device;
this.arduino.aliasSerial('capper', device);
this.arduino.aliasSerial('projector', device);
try {
connectSuccess = await this.arduino.connect('camera', device, false);
}
catch (err) {
this.log.error('Error connecting to camera, capper and projector', err);
return false;
}
}
else if (type === 'camera,capper,projector,projector_second') {
this.connected.camera = device;
this.connected.capper = device;
this.connected.projector = device;
this.connected.projector_second = device;
this.arduino.aliasSerial('capper', device);
this.arduino.aliasSerial('projector', device);
this.arduino.aliasSerial('projector_second', device);
try {
connectSuccess = await this.arduino.connect('camera', device, false);
}
catch (err) {
this.log.error('Error connecting to camera, capper, projector and projector_second', err);
return false;
}
}
return connectSuccess;
}
/**
@ -360,12 +428,14 @@ class Devices {
let d;
let cs = {};
let ps = {};
let capper = {};
let checklist = [];
this.connected = {
projector: false,
camera: false,
light: false,
projector_second: false
projector_second: false,
capper: false
};
for (let device of devices) {
try {
@ -397,15 +467,18 @@ class Devices {
}
l.arduino = this.connected.light;
if (this.connected.camera_second) {
cs = { arduino: this.connected.camera_second };
cs.arduino = this.connected.camera_second;
}
if (this.connected.projector_second) {
ps = { arduino: this.connected.projector_second };
ps.arduino = this.connected.projector_second;
}
if (this.connected.capper) {
capper.arduino = this.connected.capper;
}
if (this.settings.state.camera && this.settings.state.camera.intval) {
c.intval = this.settings.state.camera.intval;
}
return this.ready(p, c, l, cs, ps);
return this.ready(p, c, l, cs, ps, capper);
}
/**
*
@ -419,7 +492,7 @@ class Devices {
});
if (match.length === 0) {
deviceEntry = {
type: type
type
};
deviceEntry[which] = device;
this.settings.state.devices.push(deviceEntry);
@ -430,7 +503,7 @@ class Devices {
/**
*
**/
ready(projector, camera, light, camera_second, projector_second) {
ready(projector, camera, light, camera_second, projector_second, capper) {
let args = {
camera,
projector,
@ -452,6 +525,11 @@ class Devices {
this.mainWindow.setSize(800, 800);
}
}
if (capper && capper.arduino) {
args.capper = capper;
this.mainWindow.setSize(800, 800);
this.settings.update('capper', capper);
}
this.settings.update('camera', camera);
this.settings.update('projector', projector);
this.settings.update('light', light);

File diff suppressed because one or more lines are too long

1
app/lib/display/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

13
app/lib/exec/index.d.ts vendored Normal file
View File

@ -0,0 +1,13 @@
declare const execRaw: any;
/**
* Promisified child_process.exec
*
* @param cmd
* @param arg
* @param opts See child_process.exec node docs
* @param {stream.Writable} opts.stdout If defined, child process stdout will be piped to it.
* @param {stream.Writable} opts.stderr If defined, child process stderr will be piped to it.
*
* @returns {Promise<{ stdout: string, stderr: stderr }>}
*/
declare function exec(...args: string[]): Promise<unknown>;

8
app/lib/exit/index.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
/**
* Exit process with either a 0 code or other
* specified failure code. Print message to console first.
*
* @param {string} msg Reason for exit
* @param {integer} code process exit code, default 0
**/
declare function exit(msg: string, code?: number): void;

1
app/lib/ffmpeg/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

1
app/lib/ffprobe/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

1
app/lib/filmout/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

15
app/lib/frame/index.d.ts vendored Normal file
View File

@ -0,0 +1,15 @@
interface RGBA {
r: number;
g: number;
b: number;
a: number;
}
export default class Frame {
static info(imagePath: string): Promise<{
width: any;
height: any;
}>;
static solidColor(width: number, height: number, color: RGBA): Promise<unknown>;
static blend(inPath: any, color: RGBA, imagePath: string): Promise<string>;
}
export {};

9
app/lib/intval/index.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
declare class Intval {
private _baseUrl;
private req;
constructor(url: string);
move(): Promise<unknown>;
setDir(dir: boolean): Promise<unknown>;
setExposure(exposure: number, cb: Function): Promise<unknown>;
connect(cb: Function): void;
}

1
app/lib/light/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

1
app/lib/log/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

243
app/lib/mscript/index.d.ts vendored Normal file
View File

@ -0,0 +1,243 @@
/** @module lib/mscript */
interface RGB extends Array<number> {
[index: number]: number;
}
/** class Mscript */
export default class Mscript {
output: any;
lines: string[];
cam: number;
cam2: number;
proj: number;
proj2: number;
color: string;
loops: any[];
rec: number;
two: string;
three: string;
four: string;
arr: any[];
meta: string[];
target: number;
dist: number;
variables: any;
/**
* @constructor
* Create new Mscript interpreter
**/
constructor();
/**
* Clear the state of the script
*/
clear(): void;
/**
* Main function, accepts multi-line string, parses into lines
* and interprets the instructions from the text. Returns an array
* of steps to be fed into the mcopy sequence.
*
* @param {string} text Mscript text to interpret
* @param {function} callback Function to call when string is interpreted
*
* @returns {object} if callback is not provided
*/
interpret(text: string, callback?: Function): any;
/**
* Interprets variables for complex sequence behavior.
* TODO: Fully implement, add test coverage
*
* @param {string} line Line containing a variable assignment
*
**/
variable(line: string): void;
/**
* Replace variable with value at time of interpretation
* TODO: Implement this please
*
* @param {string} line Line containing variable to be replaced with value
*
* @returns {string} New string to be interpreted
**/
variable_replace(line: string): string;
/**
* Interpret a basic two character command
*
* @param {string} line Line of script to interpret
* @param {string} short The short command to use
*/
basic_cmd(line: string, short: string): void;
/**
* Start a new loop
*
* @param {string} line Line to evaluate as either loop or fade
* @param {boolean} fade Flag as true if fade
*/
new_loop(line: string, fade?: boolean): void;
/**
* Close the most recent loop
*
* @param {string} line Line to interpret
*/
end_loop(line: string): void;
/**
* Move camera to explicitly-defined frame
*
* @param {string} line Line to interpret with camera move statement
*/
move_cam(line: string): void;
/**
* Move secondary camera to explicitly-defined frame
*
* @param {string} line Line to interpret with camera move statement
*/
move_cam2(line: string): void;
/**
* Move projector to explicitly-defined frame
*
* @param {string} line Line containing `move` statement to interpret
*/
move_proj(line: string): void;
/**
* Move projector to explicitly-defined frame
*
* @param {string} line Line containing `move` statement to interpret
*/
move_proj2(line: string): void;
/**
* Set the state of either the cam or projector
*
* @param line {string} String containing set statement
*/
set_state(line: string): void;
/**
* Return the last loop
*
* @returns {object}
*/
last_loop(): any;
/**
* Return the second-last loop
*
* @returns {object} Loop array
*/
parent_loop(): any;
/**
* Extract the loop count integer from a LOOP cmd
*
* @returns {integer} Loop count in string parsed into integer
*/
loop_count(str: string): number;
/**
* Execute a fade of frame length, from color to another color
*
* @param {string} line Line containing a fade initiator
*/
fade(line: string): void;
/**
* Extract the fade length integer from a FADE cmd
*
* @param {string} str Line containing the length of fade in frames
*/
fade_count(str: string): number;
/**
* Extract the start color from a string
*
* @param {string} str Line containing the start color value in a fade initiator
*
* @returns {array} Array containing RGB color values
*/
fade_start(str: string): RGB;
/**
* Extract the end color from a string
*
* @param {string} str Line containing the end color value in a fade initiator
*
* @returns {array} Array containing RGB color values
*/
fade_end(str: string): RGB;
/**
* Determine the state of a fade at a particular frame in the sequence, x
*
* @param {array} start Color the fade starts at
* @param {array} end Color the fade finishes at
* @param {integer} len Total length of the fade in frames
* @param {integer} x Position of the fade to get color value of
*
* @returns {array} Array containing RGB color values
*/
fade_rgb(start: RGB, end: RGB, len: number, x: number): string;
/**
* Parse string into array of RGB color values. 0-255 octet.
*
* @param {string} str String containing only color values as `#,#,#`
**/
rgb(str: string): RGB;
/**
* Cast RGB color values as string
*
* @param {array} arr Array to join into string
*
* @returns {string} String of RGB values
**/
rgb_str(arr: RGB): string;
/**
* Increase the state of a specific object, such as the camera/projector,
* by the value defined in val.
*
* @param {string} cmd String representing command to interpret and update state
*/
update(cmd: string, val?: number): void;
/**
* Split string on command, turn into array of commands
* as long as count variable. Default 1.
*
* @param {string} str String to split
* @param {string} cmd String representing command to split at
*
* @returns {array} Array containing commands
*/
str_to_arr(str: string, cmd: string): string[];
/**
* Split a string on a command to extract data for light array
*
* @param {string} str String containing light command
* @param {string} cmd String representing command
*
* @returns {array} An RGB array containing the color values
*/
light_to_arr(str: string, cmd: string): RGB;
/**
* Split a string to extract an rgb color value
*
* @param {string} Color string assign to color property
*/
light_state(str: string): void;
/**
* Interpret a pause command
*
* @param {string} line String containing pause command
**/
pause(line: string): void;
/**
* Interpret an alert command
*
* @param {string} line String containing pause command
**/
alert(line: string): void;
/**
* Throw an error with specific message
*
* @param {string} msg Error message to print
*/
fail(msg: string): void;
/**
* Determine if array contains matching elements of
* another array
*
* @param {Array} arr Original array to compare
* @param {Array} arr2 Array to compare elements from
*
* @returns {boolean} Whether arr contains elements in arr2
**/
contains(arr: string[], arr2: string[]): boolean;
}
export {};

View File

@ -1,4 +1,5 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const BLACK = '0,0,0';
const WHITE = '255,255,255';
const CMD = [
@ -7,7 +8,35 @@ const CMD = [
'BF',
'CB',
'PB',
'BB'
'BB',
'C2F',
'C2B',
'CCF',
'CCB',
'P2F',
'P2B',
'PPF',
'PPB',
'CFCB',
'CBCF',
'PFPB',
'PBPF'
];
const CAMERA_SECONDARY = [
'C2F',
'C2B',
'CCF',
'CCB',
'CFCB',
'CBCF'
];
const PROJECTOR_SECONDARY = [
'P2F',
'P2B',
'PPF',
'PPB',
'PFPB',
'PBPF'
];
const ALTS = {
'CF': ['CAMERA FORWARD', 'CAM FORWARD'],
@ -17,7 +46,19 @@ const ALTS = {
'PB': ['PROJECTOR FORWARD', 'PROJ FORWARD', 'PROJECTOR BACK', 'PROJ BACK'],
'BB': ['BLACK BACKWARD', 'BLACK BACK', 'BLANK BACK'],
'L ': ['LIGHT', 'COLOR', 'LAMP'],
'F ': ['FADE']
'F ': ['FADE'],
'C2F': ['CAMERA2 FORWARD', 'CAM2 FORWARD'],
'C2B': ['CAMERA2 BACKWARD', 'CAM2 BACKWARD', 'CAMERA2 BACK', 'CAM2 BACK'],
'CCF': ['CAMERAS FORWARD', 'CAMS FORWARD'],
'CCB': ['CAMERAS BACKWARD', 'CAMS BACKWARD', 'CAMERAS BACK', 'CAMS BACK'],
'P2F': ['PROJECTOR2 FORWARD', 'PROJ2 FORWARD'],
'P2B': ['PROJECTOR2 BACKWARD', 'PROJ2 BACKWARD', 'PROJECTOR2 BACK', 'PROJ2 BACK'],
'PPF': ['PROJECTORS FORWARD', 'PROJS FORWARD'],
'PPB': ['PROJECTORS BACKWARD', 'PROJS BACKWARD', 'PROJECTORS BACK', 'PROJS BACK'],
'CFCB': [],
'CBCF': [],
'PFPB': [],
'PBPF': []
};
const PAUSE = 'PAUSE';
const ALERT = 'ALERT';
@ -56,11 +97,15 @@ class Mscript {
clear() {
this.lines = [];
this.cam = 0;
this.cam2 = 0;
this.proj = 0;
this.proj2 = 0;
this.color = '';
this.loops = [];
this.rec = -1;
this.two = '';
this.three = '';
this.four = '';
this.arr = [];
this.meta = [];
this.target = 0; //move to target using CAM # or PROJ #
@ -78,7 +123,7 @@ class Mscript {
*
* @returns {object} if callback is not provided
*/
interpret(text, callback) {
interpret(text, callback = null) {
this.clear();
if (typeof text === 'undefined') {
return this.fail('No input');
@ -93,11 +138,19 @@ class Mscript {
});
for (let line of this.lines) {
this.two = line.substring(0, 2);
if (CMD.indexOf(this.two) !== -1) {
this.basic_cmd(line);
this.three = line.substring(0, 3);
this.four = line.substring(0, 4);
if (CMD.indexOf(this.four) !== -1) {
this.basic_cmd(line, this.four);
}
else if (CMD.indexOf(this.three) !== -1) {
this.basic_cmd(line, this.three);
}
else if (CMD.indexOf(this.two) !== -1) {
this.basic_cmd(line, this.two);
}
else if (startsWith(line, PAUSE)) {
this.pause(line);
//this.pause(line);
}
else if (startsWith(line, ALERT)) {
this.alert(line);
@ -117,9 +170,15 @@ class Mscript {
else if (startsWith(line, 'END')) {
this.end_loop(line);
}
else if (startsWith(line, 'CAM')) { //directly go to that frame (black?)
else if (startsWith(line, 'CAM2')) { //directly go to that frame
this.move_cam2(line);
}
else if (startsWith(line, 'CAM')) { //directly go to that frame
this.move_cam(line);
}
else if (startsWith(line, 'PROJ2')) { //directly go to that frame
this.move_proj2(line);
}
else if (startsWith(line, 'PROJ')) { //directly go to that frame
this.move_proj(line);
}
@ -130,18 +189,19 @@ class Mscript {
//comments
//ignore while parsing
}
else if (startsWith(line, 'ALERT')) {
}
else if (startsWith(line, 'PAUSE')) {
this.pause(line);
}
}
this.output.success = true;
this.output.arr = this.arr; //all instructions
this.output.meta = this.meta; //all metadata for instructions
this.output.cam = this.cam;
this.output.proj = this.proj;
if (typeof callback !== 'undefined') {
if (this.contains(this.arr, CAMERA_SECONDARY)) {
this.output.cam2 = this.cam2;
}
if (this.contains(this.arr, PROJECTOR_SECONDARY)) {
this.output.proj2 = this.proj2;
}
if (typeof callback !== 'undefined' && callback != null) {
//should only be invoked by running mscript.tests()
callback(this.output);
}
@ -203,25 +263,26 @@ class Mscript {
* Interpret a basic two character command
*
* @param {string} line Line of script to interpret
* @param {string} short The short command to use
*/
basic_cmd(line) {
basic_cmd(line, short) {
if (this.rec !== -1) {
//hold generated arr in state loop array
this.loops[this.rec].arr
.push.apply(this.loops[this.rec].arr, this.str_to_arr(line, this.two));
.push.apply(this.loops[this.rec].arr, this.str_to_arr(line, short));
this.loops[this.rec].meta
.push.apply(this.loops[this.rec].meta, this.light_to_arr(line, this.two));
.push.apply(this.loops[this.rec].meta, this.light_to_arr(line, short));
}
else {
this.arr.push.apply(this.arr, this.str_to_arr(line, this.two));
this.meta.push.apply(this.meta, this.light_to_arr(line, this.two));
this.arr.push.apply(this.arr, this.str_to_arr(line, short));
this.meta.push.apply(this.meta, this.light_to_arr(line, short));
}
}
/**
* Start a new loop
*
* @param {string} line Line to evaluate as either loop or fade
* @param {boolean} fade Flag as boolean if true
* @param {boolean} fade Flag as true if fade
*/
new_loop(line, fade) {
this.rec++;
@ -230,6 +291,8 @@ class Mscript {
meta: [],
cam: 0,
proj: 0,
cam2: 0,
proj2: 0,
cmd: line + ''
};
if (fade) {
@ -315,6 +378,50 @@ class Mscript {
}
}
}
/**
* Move secondary camera to explicitly-defined frame
*
* @param {string} line Line to interpret with camera move statement
*/
move_cam2(line) {
this.target = parseInt(line.split('CAM2 ')[1]);
if (this.rec !== -1) {
if (this.target > this.cam2) {
this.dist = this.target - this.cam2;
for (let x = 0; x < this.dist; x++) {
this.loops[this.rec].arr.push('C2F');
this.loops[this.rec].meta.push(BLACK);
this.update('C2F');
}
}
else {
this.dist = this.cam2 - this.target;
for (let x = 0; x < this.dist; x++) {
this.loops[this.rec].arr.push('C2B');
this.loops[this.rec].meta.push(BLACK);
this.update('C2B');
}
}
}
else {
if (this.target > this.cam2) {
this.dist = this.target - this.cam2;
for (let x = 0; x < this.dist; x++) {
this.arr.push('C2F');
this.meta.push(BLACK);
this.update('C2F');
}
}
else {
this.dist = this.cam2 - this.target;
for (let x = 0; x < this.dist; x++) {
this.arr.push('C2B');
this.meta.push(BLACK);
this.update('C2B');
}
}
}
}
/**
* Move projector to explicitly-defined frame
*
@ -359,13 +466,63 @@ class Mscript {
}
}
}
/**
* Move projector to explicitly-defined frame
*
* @param {string} line Line containing `move` statement to interpret
*/
move_proj2(line) {
this.target = parseInt(line.split('PROJ2 ')[1]);
if (this.rec !== -1) {
if (this.target > this.proj2) {
this.dist = this.target - this.proj2;
for (let x = 0; x < this.dist; x++) {
this.loops[this.rec].arr.push('P2F');
this.loops[this.rec].meta.push('');
this.update('P2F');
}
}
else {
this.dist = this.proj2 - this.target;
for (let x = 0; x < this.dist; x++) {
this.loops[this.rec].arr.push('P2B');
this.loops[this.rec].meta.push('');
this.update('P2B');
}
}
}
else {
if (this.target > this.proj2) {
this.dist = this.target - this.proj2;
for (let x = 0; x < this.dist; x++) {
this.arr.push('P2F');
this.meta.push('');
this.update('P2F');
}
}
else {
this.dist = this.proj2 - this.target;
for (let x = 0; x < this.dist; x++) {
this.arr.push('P2B');
this.meta.push('');
this.update('P2B');
}
}
}
}
/**
* Set the state of either the cam or projector
*
* @param line {string} String containing set statement
*/
set_state(line) {
if (startsWith(line, 'SET CAM')) {
if (startsWith(line, 'SET CAM2')) {
parseInt(line.split('SET CAM2')[1]);
}
else if (startsWith(line, 'SET PROJ2')) {
this.cam2 = parseInt(line.split('SET PROJ2')[1]);
}
else if (startsWith(line, 'SET CAM')) {
this.cam = parseInt(line.split('SET CAM')[1]);
}
else if (startsWith(line, 'SET PROJ')) {
@ -523,7 +680,7 @@ class Mscript {
this.cam -= val;
}
else {
this.loops[this.rec].cam--;
this.loops[this.rec].cam -= val;
}
}
else if (cmd === 'PF') {
@ -539,7 +696,7 @@ class Mscript {
this.proj -= val;
}
else {
this.loops[this.rec].proj--;
this.loops[this.rec].proj -= val;
}
}
else if (cmd === 'BF') {
@ -558,6 +715,118 @@ class Mscript {
this.loops[this.rec].cam -= val;
}
}
else if (cmd === 'C2F') {
if (this.rec === -1) {
this.cam2 += val;
}
else {
this.loops[this.rec].cam2 += val;
}
}
else if (cmd === 'C2B') {
if (this.rec === -1) {
this.cam2 -= val;
}
else {
this.loops[this.rec].cam2 -= val;
}
}
else if (cmd === 'CCF') {
if (this.rec === -1) {
this.cam += val;
this.cam2 += val;
}
else {
this.loops[this.rec].cam2 += val;
this.loops[this.rec].cam2 += val;
}
}
else if (cmd === 'CCB') {
if (this.rec === -1) {
this.cam -= val;
this.cam2 -= val;
}
else {
this.loops[this.rec].cam2 -= val;
this.loops[this.rec].cam2 -= val;
}
}
else if (cmd === 'P2F') {
if (this.rec === -1) {
this.proj2 += val;
}
else {
this.loops[this.rec].proj2 += val;
}
}
else if (cmd === 'P2B') {
if (this.rec === -1) {
this.proj2 -= val;
}
else {
this.loops[this.rec].proj2 -= val;
}
}
else if (cmd === 'PPF') {
if (this.rec === -1) {
this.proj += val;
this.proj2 += val;
}
else {
this.loops[this.rec].proj += val;
this.loops[this.rec].proj2 += val;
}
}
else if (cmd === 'PPB') {
if (this.rec === -1) {
this.proj -= val;
this.proj2 -= val;
}
else {
this.loops[this.rec].proj -= val;
this.loops[this.rec].proj2 -= val;
}
}
else if (cmd === 'CFCB') {
if (this.rec === -1) {
this.cam += val;
this.cam2 -= val;
}
else {
this.loops[this.rec].cam += val;
this.loops[this.rec].cam2 -= val;
}
}
else if (cmd === 'CBCF') {
if (this.rec === -1) {
this.cam -= val;
this.cam2 += val;
}
else {
this.loops[this.rec].cam -= val;
this.loops[this.rec].cam2 += val;
}
}
else if (cmd === 'PFPB') {
if (this.rec === -1) {
this.proj += val;
this.proj2 -= val;
}
else {
this.loops[this.rec].proj += val;
this.loops[this.rec].proj2 -= val;
}
}
else if (cmd === 'PBPF') {
if (this.rec === -1) {
this.proj -= val;
this.proj2 += val;
}
else {
this.loops[this.rec].proj -= val;
this.loops[this.rec].proj2 += val;
}
}
else if (cmd === 'L ') {
}
}
@ -654,7 +923,7 @@ class Mscript {
.push(lenStr);
}
else {
this.arr.push('AL');
this.arr.push('PA');
this.meta.push(lenStr);
}
}
@ -671,11 +940,11 @@ class Mscript {
this.loops[this.rec].arr
.push('AL');
this.loops[this.rec].meta
.push(msg);
.push(line);
}
else {
this.arr.push('AL');
this.meta.push(msg);
this.meta.push(line);
}
}
/**
@ -686,6 +955,19 @@ class Mscript {
fail(msg) {
throw new Error(msg);
}
/**
* Determine if array contains matching elements of
* another array
*
* @param {Array} arr Original array to compare
* @param {Array} arr2 Array to compare elements from
*
* @returns {boolean} Whether arr contains elements in arr2
**/
contains(arr, arr2) {
return arr.some(r => arr2.includes(r));
}
}
exports.default = Mscript;
module.exports = Mscript;
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

1
app/lib/processing/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

2
app/lib/proj/index.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
/** class representing the Projector features **/
export {};

1
app/lib/sequencer/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

View File

@ -230,8 +230,7 @@ class Sequencer {
const cmdOriginal = this.arr[x].cmd;
const cmd = this.CMDS[cmdOriginal];
this.log.info(`CMD: '${cmdOriginal}' -> ${cmd}`);
//I wrote this when I was very tired and delirious
return await this.cmd[cmd]();
return await this.cmd[cmd](this.arr[x]);
}
}
module.exports = function (cfg, cmd, ui) {

File diff suppressed because one or more lines are too long

1
app/lib/settings/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

View File

@ -18,7 +18,8 @@ class Settings {
profile: 'mcopy',
camera: {},
projector: {},
light: {}
light: {},
capper: {}
};
this.state = this.freshState();
}

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/settings/index.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/settings/index.ts"],"names":[],"mappings":"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"}

1
app/lib/system/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

27
app/lib/ui/alert.js Normal file
View File

@ -0,0 +1,27 @@
'use strict';
let alertObj;
class Alert {
constructor() {
this.id = 'alert';
}
init() {
this.listen();
}
start(msg) {
alert(msg);
this.end();
}
end() {
const obj = {};
ipcRenderer.sendSync(this.id, obj);
}
listen() {
ipcRenderer.on(this.id, (function (event, arg) {
this.start(arg.msg);
}).bind(this));
}
;
}
alertObj = new Alert();
module.exports = alertObj;
//# sourceMappingURL=alert.js.map

1
app/lib/ui/alert.js.map Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"alert.js","sourceRoot":"","sources":["../../src/lib/ui/alert.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAOb,IAAI,QAAgB,CAAC;AAErB,MAAM,KAAK;IAGV;QAFA,OAAE,GAAY,OAAO,CAAC;IAGtB,CAAC;IAEM,IAAI;QACV,IAAI,CAAC,MAAM,EAAE,CAAC;IACf,CAAC;IAEM,KAAK,CAAE,GAAY;QACzB,KAAK,CAAC,GAAG,CAAC,CAAC;QACX,IAAI,CAAC,GAAG,EAAE,CAAC;IACZ,CAAC;IAEO,GAAG;QACV,MAAM,GAAG,GAAS,EAAE,CAAC;QAErB,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IACpC,CAAC;IAEO,MAAM;QACb,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,UAAU,KAAa,EAAE,GAAS;YAC1D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChB,CAAC;IAAA,CAAC;CAEF;AAED,QAAQ,GAAG,IAAI,KAAK,EAAE,CAAC;AACvB,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC"}

72
app/lib/ui/capper.js Normal file
View File

@ -0,0 +1,72 @@
'use strict';
let capper;
class Capper {
constructor() {
this.enabled = false;
this.queue = {};
this.lock = false;
this.id = 'capper';
this.state = false;
}
init() {
this.listen();
}
enable() {
$('.black').addClass('on');
$('#cmd_black_forward').parent().removeClass('hide');
$('#cmd_black_backward').parent().removeClass('hide');
$('#cmd_capper_on').parent().removeClass('hide');
$('#cmd_capper_off').parent().removeClass('hide');
this.enabled = true;
}
capper(state, callback) {
let obj;
if (this.lock) {
return false;
}
obj = {
state,
id: uuid()
};
ipcRenderer.sendSync(this.id, obj);
if (typeof callback !== 'undefined') {
obj.callback = callback;
}
this.queue[obj.id] = obj;
this.lock = true;
this.state = state;
if (state) {
$('#cmd_capper_on').addClass('active');
$('#cmd_capper_off').removeClass('active');
}
else {
$('#cmd_capper_off').addClass('active');
$('#cmd_capper_on').removeClass('active');
}
}
end(c, id, ms) {
if (c === cfg.arduino.cmd.capper_on) {
this.state = true;
}
else if (c === cfg.arduino.cmd.capper_off) {
this.state = false;
}
if (typeof this.queue[id] !== 'undefined') {
if (typeof this.queue[id].callback !== 'undefined') {
this.queue[id].callback(ms);
}
delete this.queue[id];
this.lock = false;
}
}
listen() {
ipcRenderer.on(this.id, function (event, arg) {
capper.end(arg.cmd, arg.id, arg.ms);
return event.returnValue = true;
});
}
;
}
capper = new Capper();
module.exports = capper;
//# sourceMappingURL=capper.js.map

1
app/lib/ui/capper.js.map Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"capper.js","sourceRoot":"","sources":["../../src/lib/ui/capper.ts"],"names":[],"mappings":"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"}

View File

@ -155,24 +155,63 @@ cmd.black_forward = function (callback) {
if (callback) { callback(ms); }
};
$('#cmd_black_forward').addClass('active');
if (!cam.dir) {
cam.set(true, function () {
setTimeout( function () {
light.display(off);
light.set(off, function () {
setTimeout( function () {
cam.move(res);
}, cfg.arduino.serialDelay);
});
}, cfg.arduino.serialDelay);
});
if (capper.enabled) {
cam.set(true, function () {
setTimeout( function () {
capper.capper(true, function () {
setTimeout( function () {
light.display(off);
light.set(off, function () {
setTimeout( function () {
cam.move(function () {
setTimeout(function () {
capper.capper(false, res);
}, cfg.arduino.serialDelay);
});
}, cfg.arduino.serialDelay);
});
}, cfg.arduino.serialDelay)
})
}, cfg.arduino.serialDelay);
});
} else {
cam.set(true, function () {
setTimeout( function () {
light.display(off);
light.set(off, function () {
setTimeout( function () {
cam.move(res);
}, cfg.arduino.serialDelay);
});
}, cfg.arduino.serialDelay);
});
}
} else {
light.display(off);
light.set(off, function () {
setTimeout(function () {
cam.move(res);
}, cfg.arduino.serialDelay);
});
if (capper.enabled) {
capper.capper(true, function () {
setTimeout( function () {
light.display(off);
light.set(off, function () {
setTimeout( function () {
cam.move(function () {
setTimeout(function () {
capper.capper(false, res);
}, cfg.arduino.serialDelay);
});
}, cfg.arduino.serialDelay);
});
}, cfg.arduino.serialDelay);
});
} else {
light.display(off);
light.set(off, function () {
setTimeout(function () {
cam.move(res);
}, cfg.arduino.serialDelay);
});
}
}
};
/**
@ -226,21 +265,57 @@ cmd.black_backward = function (callback) {
};
$('#cmd_black_backward').addClass('active');
if (cam.dir) {
cam.set(false, function () {
if (capper.enabled) {
cam.set(false, function () {
setTimeout( function () {
capper.capper(true, function () {
setTimeout(function () {
light.display(off);
light.set(off, function () {
cam.move(function () {
setTimeout(function () {
capper.capper(false, res);
}, cfg.arduino.serialDelay);
});
});
}, cfg.arduino.serialDelay);
});
}, cfg.arduino.serialDelay);
});
} else {
cam.set(false, function () {
setTimeout(function () {
light.display(off);
light.set(off, function () {
cam.move(res);
});
}, cfg.arduino.serialDelay);
});
}
} else {
if (capper.enabled) {
capper.capper(true, function () {
setTimeout( function () {
light.display(off);
light.set(off, function () {
setTimeout( function () {
cam.move(function () {
setTimeout(function () {
capper.capper(false, res);
}, cfg.arduino.serialDelay);
});
}, cfg.arduino.serialDelay);
});
}, cfg.arduino.serialDelay);
});
} else {
setTimeout(function () {
light.display(off);
light.set(off, function () {
cam.move(res);
});
}, cfg.arduino.serialDelay);
});
} else {
setTimeout(function () {
light.display(off);
light.set(off, function () {
cam.move(res);
});
}, cfg.arduino.serialDelay);
}
}
};
@ -534,4 +609,32 @@ cmd.projector_second_to = function (t) {
}
}
/**
* Turn the capper on (block the camera)
*
* @param {function} callback Function to call after capper is on
**/
cmd.capper_on = function (callback) {
'use strict';
var res = function (ms) {
gui.updateState();
if (callback) { callback(ms); }
};
capper.capper(true, res);
};
/**
* Turn the capper off (not blocking the camera)
*
* @param {function} callback Function to call after capper is off
**/
cmd.capper_off = function (callback) {
'use strict';
var res = function (ms) {
gui.updateState();
if (callback) { callback(ms); }
};
capper.capper(false, res);
};
module.exports = cmd;

View File

@ -85,11 +85,6 @@ class Devices {
}
//devices.profile(arg.profile)
}
seq.set(0, cfg.cmd.camera_forward);
seq.set(1, cfg.cmd.projector_forward);
grid.state(0);
grid.state(1);
seq.stats();
if (arg.projector_second) {
//add second row of projector pads to grid
proj.second.enable();
@ -98,6 +93,15 @@ class Devices {
//add second row of camera pads to grid
cam.second.enable();
}
if (arg.capper) {
//add capper features to grid
capper.enable();
}
seq.set(0, cfg.cmd.camera_forward);
seq.set(1, cfg.cmd.projector_forward);
grid.state(0);
grid.state(1);
seq.stats();
return event.returnValue = true;
});
}

File diff suppressed because one or more lines are too long

View File

@ -6,6 +6,9 @@ let grid;
class Grid {
constructor() {
this.swatchesElem = {};
this.projector_cmds = [
'PF', 'PB', 'P2F', 'P2B', 'PPF', 'PPB'
];
}
init() {
this.refresh();
@ -24,8 +27,8 @@ class Grid {
const step = seq.grid[x];
let className;
let className2;
elem.prop('checked', false);
if (typeof step !== 'undefined') {
elem.prop('checked', false);
if (step.cmd === cfg.cmd.cameras_forward) {
className = cfg.cmd.camera_forward;
className2 = cfg.cmd.camera_second_forward;
@ -58,6 +61,14 @@ class Grid {
className = cfg.cmd.projector_backward;
className2 = cfg.cmd.projector_second_forward;
}
else if (step.cmd === cfg.cmd.black_forward) {
className = cfg.cmd.camera_forward;
className2 = 'black';
}
else if (step.cmd === cfg.cmd.black_backward) {
className = cfg.cmd.camera_backward;
className2 = 'black';
}
else {
className = step.cmd;
}
@ -75,6 +86,12 @@ class Grid {
.removeClass('a')
.prop('title', '');
}
if (capper.enabled && this.projector_cmds.indexOf(step.cmd) !== -1) {
$(`.black[x=${x}]`).addClass('disabled');
}
else if (capper.enabled) {
$(`.black[x=${x}]`).removeClass('disabled');
}
}
else {
lightElem.css('background', 'transparent')
@ -113,6 +130,7 @@ class Grid {
'camera_second_backward',
'projector_backward',
'projector_second_backward',
'black',
'light_set',
'numbers'
];
@ -132,6 +150,10 @@ class Grid {
elem = `<div x="${x}" class="L"></div>`;
$(cmd).append($(elem));
}
else if (cmds[i] === 'black') {
elem = `<input type="checkbox" x="${x}" class="black" />`;
$(cmd).append($(elem));
}
else {
elem = `<input type="checkbox" x="${x}" />`;
$(cmd).append($(elem).addClass(cfg.cmd[cmds[i]]));
@ -159,7 +181,24 @@ class Grid {
current = seq.grid[x].cmd + ''; // cast to string, bad hack
}
if (checked) {
if (cam.second.enabled && current.indexOf('C') !== -1) {
if (c.indexOf('black') !== -1) {
if (other === '') {
c = cfg.cmd.black_forward;
}
else if (current.indexOf('C') !== -1) {
if (other == cfg.cmd.camera_forward) {
c = cfg.cmd.black_forward;
}
else if (other === cfg.cmd.camera_backward) {
c = cfg.cmd.black_backward;
}
}
else if (current.indexOf('P') !== -1) {
$(elem).prop('checked', false);
return;
}
}
else if (cam.second.enabled && current.indexOf('C') !== -1) {
if (c === cfg.cmd.camera_forward) {
if (other === cfg.cmd.camera_second_forward) {
c = cfg.cmd.cameras_forward;
@ -254,7 +293,27 @@ class Grid {
seq.set(x, c);
}
else {
if (cam.second.enabled && current.indexOf('C') !== -1) {
if (c.indexOf('black') !== -1) {
if (current === 'BF' || current === 'BB') {
if (other === cfg.cmd.camera_forward) {
c = cfg.cmd.camera_forward;
}
else if (other === cfg.cmd.camera_backward) {
c = cfg.cmd.camera_backward;
}
}
else if (current.indexOf('P') !== -1) {
$(elem).prop('checked', false);
return;
}
}
else if (other === 'black' && current === cfg.cmd.camera_forward) {
c = '';
}
else if (other === 'black' && current === cfg.cmd.camera_backward) {
c = '';
}
else if (cam.second.enabled && current.indexOf('C') !== -1) {
if (current === cfg.cmd.cameras_forward) {
if (other === cfg.cmd.camera_second_forward) {
c = cfg.cmd.camera_second_forward;

File diff suppressed because one or more lines are too long

View File

@ -1,231 +1,284 @@
const mse = {};
'use strict';
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/// <reference path ="jquery.d.ts"/>
const mscript_1 = __importDefault(require("mscript"));
/******
Mscript GUI
Mscript GUI
*******/
mse.mscript = {};
mse.mscript.editor = {};
mse.mscript.data = {};
mse.mscript.raw = '';
mse.mscript.init = function () {
'use strict';
$('#editor').val('CF 1\nPF 1');
mse.mscript.editor = CodeMirror.fromTextArea(document.getElementById('editor'), {
lineNumbers: true,
mode: 'python',
matchBrackets: true,
theme: 'monokai'
});
mse.mscript.editor.setSize(null, $(window).height() - $('footer').eq(0).height() - 30);
mse.mscript.editor.on('change', function (e) {
//
});
$(document).on('resize', function (e) {
mse.mscript.editor.setSize(null, $(window).height() - $('footer').eq(0).height() - 30);
});
};
mse.mscript.open = function () {
'use strict';
mse.mscript.editor.setSize(null, $(window).height() - $('footer').eq(0).height() - 30);
mse.mscript.editor.refresh();
};
mse.mscript.fromSequence = function () {
//ehhhhh
'use strict';
let str;
let tmp = [];
let cont;
let cmd;
//str = seq.grid.map(step => { return step.cmd }).join('\n'); //quick hack
//console.dir(seq.grid);
for (let step of seq.grid) {
if (!step || !step.cmd) continue;
cmd = step.cmd;
if (tmp.length > 0 && tmp[tmp.length - 1].cmd === cmd) {
tmp[tmp.length - 1].num++;
continue;
}
tmp.push({ cmd : cmd, num : 1 });
}
tmp = tmp.map(line => {
return `${line.cmd} ${line.num}`
})
//console.dir(tmp)
if (seq.gridLoops > 1) {
tmp.map(line => {
return ` ${line}`;
})
tmp.reverse();
tmp.push(`LOOP ${seq.gridLoops}`);
tmp.reverse();
tmp.push('END');
}
str = tmp.join('\n');
nav.change('script');
cont = confirm(`Are you sure you want to over-write the current sequence?`);
if (cont) {
mse.mscript.editor.getDoc().setValue(str);
}
};
mse.mscript.toGUI = function () {
'use strict';
let c;
let step;
for (let x = 0; x < mse.mscript.data.arr.length; x++) {
c = mse.mscript.data.arr[x];
seq.set(x, c);
if (c === 'CF' || c === 'CB') {
if (typeof mse.mscript.data.meta[x] !== 'undefined' && mse.mscript.data.meta[x] !== '') {
seq.setLight(x, mse.mscript.data.meta[x]);
} else {
seq.setLight(x, light.color);
}
} else {
//unset light?
}
grid.state(x);
}
};
mse.mscript.toSequence = function () {
'use strict';
const data = mse.mscript.editor.getValue();
let cont;
if (data !== mse.mscript.raw) {
cont = confirm(`Current script has not been compiled. Compile first?`);
if (cont) {
mse.mscript.compile()
}
}
mse.console.print(`Sending compiled script to GUI sequencer...`);
seq.clear();
mse.mscript.toGUI();
grid.refresh();
seq.stats();
return nav.change('sequencer');
class MscriptGUI {
constructor() {
this.editor = {};
this.data = {};
this.raw = '';
}
/**
* Initializes the mscript GUI. Sets up CodeMirror instance,
* binds events and sets height of editor.
**/
init() {
const startingScript = `CF 1
PF 1`;
const editorHeight = $(window).height() - $('footer').eq(0).height() - 30;
const editorElem = document.getElementById('editor');
const editorConfig = {
lineNumbers: true,
mode: 'python',
matchBrackets: true,
theme: 'monokai'
};
$('#editor').val(startingScript);
this.editor = CodeMirror.fromTextArea(editorElem, editorConfig);
this.editor.setSize(null, editorHeight);
this.editor.on('change', (e) => { });
$(document).on('resize', function (e) {
this.editor.setSize(null, editorHeight);
}.bind(this));
}
/**
* Callback for when open event occurs.
**/
open() {
//recalcuate in case resize has occurred needed
const editorHeight = $(window).height() - $('footer').eq(0).height() - 30;
this.editor.setSize(null, editorHeight);
this.editor.refresh();
}
/**
* Create script from the sequencer's current state.
* Previous comment: ehhhh
* TODO: Make this smarter.
**/
fromSequence() {
let str;
let tmp = [];
let cont;
let cmd;
//str = seq.grid.map(step => { return step.cmd }).join('\n'); //quick hack
//console.dir(seq.grid);
for (let step of seq.grid) {
if (!step || !step.cmd) {
continue;
}
cmd = step.cmd;
if (tmp.length > 0 && tmp[tmp.length - 1].cmd === cmd) {
tmp[tmp.length - 1].num++;
continue;
}
tmp.push({ cmd, num: 1 });
}
tmp = tmp.map(line => {
return `${line.cmd} ${line.num}`;
});
if (seq.gridLoops > 1) {
tmp.map(line => {
return ` ${line}`;
});
tmp.reverse();
tmp.push(`LOOP ${seq.gridLoops}`);
tmp.reverse();
tmp.push('END');
}
str = tmp.join('\n');
nav.change('script');
cont = confirm(`Are you sure you want to over-write the current sequence?`);
if (cont) {
this.editor.getDoc().setValue(str);
}
}
/**
* Take current compiled mscript state and send it to the sequencer
* GUI. TODO: Add confirm step if sequence is longer than X steps.
* TODO: Make this smarter (detect outer non-fade loop and assign to loop counter)
**/
toGUI() {
let c;
let step;
for (let x = 0; x < this.data.arr.length; x++) {
c = this.data.arr[x];
seq.set(x, c);
if (c === 'CF' || c === 'CB') {
if (typeof this.data.meta[x] !== 'undefined' && this.data.meta[x] !== '') {
seq.setLight(x, this.data.meta[x]);
}
else {
seq.setLight(x, light.color);
}
}
else {
//unset light?
}
grid.state(x);
}
}
/**
* Handles compilation of mscript and switches to sequencer
* GUI after confirmation questions.
**/
toSequence() {
const data = this.editor.getValue();
let cont = false;
if (data !== this.raw) {
cont = confirm(`Current script has not been compiled. Compile first?`);
if (cont) {
this.compile();
}
}
mse.console.print(`Sending compiled script to GUI sequencer...`);
seq.clear();
this.toGUI();
grid.refresh();
seq.stats();
return nav.change('sequencer');
}
/**
* Compiles text in editor using the Mscript library.
*
**/
compile() {
const data = this.editor.getValue();
const mscript = new mscript_1.default();
const output = mscript.interpret(data);
const len = output.arr.length;
const cam2 = typeof output.cam2 !== 'undefined' ? `, CAM2 : ${output.cam2}` : '';
const proj2 = typeof output.proj2 !== 'undefined' ? `, PROJ2 : ${output.proj2}` : '';
const report = `Sequence contains ${len} step${(len === 1 ? '' : 's')}, CAM: ${output.cam}, PROJ: ${output.proj}${cam2}${proj2}`;
this.raw = data;
this.data = output;
//mse.console.print(JSON.stringify(output, null, '\t') + '\n')
mse.console.print(report);
}
/**
* This function re-writes the optional "meta" attribute
* of an mcopy command object to "light". TODO: change this.
* Do not re-write this object and improve the consumers
* of the compiled data.
**/
prepare() {
const arr = [];
let obj;
for (let i = 0; i < this.data.arr.length; i++) {
obj = {
cmd: this.data.arr[i]
};
if (typeof this.data.meta[i] !== 'undefined' && this.data.meta[i] !== '') {
obj.light = this.data.meta[i];
}
else {
obj.light = light.color.join(',');
}
arr.push(obj);
}
return arr;
}
/**
* Method which compiles script if needs and then runs as a sequence.
**/
run() {
const data = this.editor.getValue();
let arr;
let cont = false;
if (data !== this.raw) {
cont = confirm(`Current script has not been compiled. Compile first?`);
if (cont) {
this.compile();
}
}
arr = this.prepare();
mse.console.print(`Started running compiled sequence...`);
gui.overlay(true);
gui.spinner(true, `Running mscript sequence...`, true, true);
return seq.exec(arr, 1);
}
}
mse.mscript.compile = function () {
'use strict';
const data = mse.mscript.editor.getValue();
const mscript = new Mscript();
let output = mscript.interpret(data);
let len = output.arr.length;
mse.mscript.raw = data;
mse.mscript.data = output;
//mse.console.print(JSON.stringify(output, null, '\t') + '\n')
mse.console.print(`Sequence contains ${len} step${(len === 1 ? '' : 's')}, CAM: ${output.cam}, PROJ: ${output.proj}`);
};
mse.mscript.prepare = function () {
'use strict';
const arr = [];
let obj;
for (let i = 0; i < mse.mscript.data.arr.length; i++) {
obj = {
cmd : mse.mscript.data.arr[i]
};
if (typeof mse.mscript.data.meta[i] !== 'undefined' && mse.mscript.data.meta[i] !== '') {
obj.light = mse.mscript.data.meta[i];
} else {
obj.light = light.color.join(',');
}
arr.push(obj);
}
return arr;
};
mse.mscript.run = function () {
'use strict';
const data = mse.mscript.editor.getValue();
let arr;
let cont;
if (data !== mse.mscript.raw) {
cont = confirm(`Current script has not been compiled. Compile first?`);
if (cont) {
mse.mscript.compile();
}
}
arr = mse.mscript.prepare();
mse.console.print(`Started running compiled sequence...`);
gui.overlay(true);
gui.spinner(true, `Running mscript sequence...`, true, true);
return seq.exec(arr, 1);
};
/*******
* gui console
* Mscript GUI Console
*******/
mse.console = {};
mse.console.elem = {};
mse.console.init = function () {
'use script';
mse.console.elem = $('#console textarea');
mse.console.elem.on('keyup', function (e) {
var code = e.keyCode || e.which;
if (code === 13) {
mse.console.exec();
e.preventDefault();
return false;
}
});
class MscriptConsole {
/**
* Initializes the console by creating the element
* containing the output text and binding to
* keyup event.
**/
init() {
this.elem = $('#console textarea');
this.elem.on('keyup', function (e) {
var code = e.keyCode || e.which;
if (code === 13) {
this.exec();
e.preventDefault();
return false;
}
}.bind(this));
}
/**
* Parse the current state of the console and get the last
* line to add to the current state array.
**/
parse() {
const lines = (this.elem.val() + '').split('\n');
const line = lines[lines.length - 2].replace('>', '').trim();
this.lines.push(line);
}
/**
* Executes the command in the last line of the console.
* TODO: implement the remaining commands. Currently only camera
* forward and backward will be executed.
**/
exec() {
let command;
this.parse();
command = this.lines[this.lines.length - 1].replace('>', '').trim();
log.info(command);
this.newLine();
if (mscript.cmd.indexOf(command) !== -1) {
if (command === 'CF') {
cmd.camera_forward(light.color);
}
else if (cmd === 'CB') {
cmd.camera_backward(light.color);
}
}
if (command === 'compile') {
mse.mscript.compile();
}
else if (command === 'run') {
mse.mscript.run();
}
}
/**
* Adds a new line to the console after an event
* and re-establishes the height of the array. Animates
* the console to scroll down to last line.
**/
newLine() {
let current = (this.elem.val() + '');
let height;
current += '> ';
this.elem.val(current);
height = this.elem[0].scrollHeight;
this.elem.animate({
scrollTop: height
}, 'normal');
}
/**
* Print string to the console and add new line
**/
print(str) {
let current = (this.elem.val() + '');
let height;
current += str;
current += '\n';
mse.console.elem.val(current);
mse.console.elem.focus();
this.newLine();
}
}
const mse = {
mscript: new MscriptGUI(),
console: new MscriptConsole()
};
mse.console.lines = [];
mse.console.parse = function () {
'use strict';
const lines = mse.console.elem.val().split('\n');
const line = lines[lines.length - 2].replace('>', '').trim();
mse.console.lines.push(line);
};
mse.console.exec = function () {
'use strict';
let command;
mse.console.parse();
command = mse.console.lines[mse.console.lines.length - 1].replace('>', '').trim();
log.info(command);
mse.console.newLine();
if (mscript.cmd.indexOf(command) !== -1) {
if (command === 'CF') {
cmd.camera_forward(light.color);
} else if (cmd === 'CB') {
cmd.camera_backward(light.color);
}
}
if (command === 'compile') {
mse.mscript.compile();
} else if (command === 'run') {
mse.mscript.run();
}
};
mse.console.newLine = function () {
'use strict';
let current = mse.console.elem.val();
let height;
current += '> ';
mse.console.elem.val(current);
height = mse.console.elem[0].scrollHeight;
mse.console.elem.animate({
scrollTop : height
},'normal');
};
mse.console.print = function (str) {
'use strict'
let current = mse.console.elem.val();
let height;
current += str;
current += '\n> ';
mse.console.elem.val(current);
mse.console.elem.focus();
height = mse.console.elem[0].scrollHeight;
mse.console.elem.animate({
scrollTop : height
},'normal');
};
module.exports = mse;
//# sourceMappingURL=mscript.js.map

File diff suppressed because one or more lines are too long

View File

@ -47,10 +47,19 @@ class Sequence {
log.info('Sequence stopped', 'SERIAL', true);
timeStr = (arg.ms < 2000) ? `${arg.ms}ms` : humanizeDuration(arg.ms);
gui.notify(`SEQUENCE`, `Sequence finished in ${timeStr}`);
if (capper.enabled && this.arr.some(this.hasCapper)) {
$('#cmd_capper_off').addClass('active');
$('#cmd_capper_on').removeClass('active');
}
}
}
return event.returnValue = true;
}
hasCapper(el) {
if (['BF', 'BB'].indexOf(el.cmd) !== -1) {
return true;
}
}
progress(step, loop) {
const elem = $('.progress-bar');
const len = this.arr.length;

File diff suppressed because one or more lines are too long

View File

@ -3,13 +3,15 @@
'use strict'
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';
//process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';
const electron = require('electron')
const { Menu, BrowserWindow, app } = electron
const { EventEmitter } = require('events')
const { join } = require('path')
require('@electron/remote/main').initialize()
const ee = new EventEmitter()
const settings = require('settings')
const system = require('system')
@ -35,6 +37,8 @@ let filmout;
let dev;
let cmd;
let seq;
let capper;
let alert;
const cfg = require('./data/cfg.json')
@ -54,19 +58,23 @@ var createWindow = function () {
skipTaskbar: true,
toolbar: false,
webPreferences : {
nodeIntegration: true,
enableRemoteModule: true
nodeIntegration : true,
enableRemoteModule: true,
contextIsolation : false
}
})
mainWindow.setMenu(null)
mainWindow.setAutoHideMenuBar(true)
mainWindow.loadURL('file://' + __dirname + '/index.html')
if (process.argv.indexOf('-d') !== -1 || process.argv.indexOf('--dev') !== -1) {
mainWindow.webContents.openDevTools()
} else {
mainWindow.setMenu(null)
mainWindow.setAutoHideMenuBar(true)
}
mainWindow.on('closed', () => {
mainWindow = null
})
require('@electron/remote/main').enable(mainWindow.webContents)
}
var errorState = function () {
@ -112,6 +120,7 @@ var init = async function () {
filmout = require('filmout')(display, ffmpeg, ffprobe, mainWindow.webContents, light)
cam = require('cam')(arduino, cfg, mainWindow.webContents, filmout)
proj = require('proj')(arduino, cfg, mainWindow.webContents, filmout)
alert = require('alert')(mainWindow.webContents)
if (dev && dev.connected && dev.connected.camera_second) {
cam2 = require('cam')(arduino, cfg, mainWindow.webContents, filmout, true)
@ -120,9 +129,13 @@ var init = async function () {
if (dev && dev.connected && dev.connected.projector_second) {
proj2 = require('proj')(arduino, cfg, mainWindow.webContents, filmout, true)
}
if (dev && dev.connected && dev.connected.capper) {
capper = require('capper')(arduino, cfg, mainWindow.webContents, filmout, true)
}
cmd = require('cmd')(cfg, proj, cam, light, cam2, proj2)
cmd = require('cmd')(cfg, proj, cam, light, alert, cam2, proj2, capper)
seq = require('sequencer')(cfg, cmd, mainWindow.webContents)
}
app.on('ready', init)

5631
app/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "mcopy-app",
"version": "1.7.0",
"version": "1.7.1",
"description": "GUI for the mcopy small gauge film optical printer platform",
"main": "main.js",
"scripts": {
@ -35,24 +35,28 @@
},
"homepage": "https://github.com/sixteenmillimeter/mcopy#readme",
"devDependencies": {
"@types/jquery": "^3.5.5",
"chai": "^4.3.0",
"electron": "^11.3.0",
"@types/codemirror": "^5.60.5",
"@types/jquery": "^3.5.14",
"chai": "^4.3.6",
"electron": "^19.0.1",
"electron-installer-common": "^0.10.3",
"electron-installer-dmg": "^3.0.0",
"electron-packager": "^15.4.0",
"electron-rebuild": "^2.3.5",
"electron-wix-msi": "^3.0.6",
"electron-installer-dmg": "^4.0.0",
"electron-packager": "^15.5.1",
"electron-rebuild": "^3.2.7",
"electron-wix-msi": "^4.0.0",
"gulp": "^4.0.2",
"gulp-concat": "^2.6.1",
"gulp-less": "^4.0.1",
"mocha": "^8.3.0",
"typescript": "^4.1.5"
"gulp-less": "^5.0.0",
"mocha": "^10.0.0",
"typescript": "^4.7.2"
},
"dependencies": {
"@electron/remote": "^2.0.8",
"alert": "file:lib/alert",
"animated-gif-detector": "^1.2.0",
"arduino": "file:lib/arduino",
"cam": "file:lib/cam",
"capper": "file:lib/capper",
"capture": "file:lib/capture",
"cmd": "file:lib/cmd",
"delay": "file:lib/delay",
@ -61,31 +65,31 @@
"exec": "file:lib/exec",
"exit": "file:lib/exit",
"ffmpeg": "file:lib/ffmpeg",
"ffmpeg-static": "^4.2.7",
"ffmpeg-static": "^5.0.0",
"ffprobe": "file:lib/ffprobe",
"ffprobe-static": "^3.0.0",
"filmout": "file:lib/filmout",
"frame": "file:lib/frame",
"fs-extra": "^9.1.0",
"humanize-duration": "^3.25.1",
"fs-extra": "^10.1.0",
"humanize-duration": "^3.27.2",
"intval": "file:lib/intval",
"jimp": "^0.16.1",
"light": "file:lib/light",
"log": "file:lib/log",
"moment": "^2.29.1",
"moment": "^2.29.3",
"mscript": "file:lib/mscript",
"node-notifier": "^9.0.0",
"node-notifier": "^10.0.1",
"processing": "file:lib/processing",
"proj": "file:lib/proj",
"request": "^2.88.2",
"sequencer": "file:lib/sequencer",
"serialport": "^9.0.7",
"serialport": "^10.4.0",
"server": "file:lib/server",
"settings": "file:lib/settings",
"spawn": "file:lib/spawn",
"system": "file:lib/system",
"uuid": "^8.3.2",
"winston": "^3.3.3"
"winston": "^3.7.2"
},
"optionalDependencies": {
"electron-installer-debian": "^3.1.0"

View File

@ -1,5 +1,7 @@
#!/bin/bash
set -e
# compile main process code
cd ..
npm run compile

View File

@ -1,7 +1,8 @@
const mcopy = {};
const { remote, ipcRenderer } = require('electron');
const dialog = require('electron').remote.dialog;
const remote = require('@electron/remote');
const { ipcRenderer } = require('electron');
const { dialog } = remote;
const notifier = require('node-notifier');
const fs = require('fs');
const uuid = require('uuid').v4;
@ -21,8 +22,10 @@ const cmd = require('./lib/ui/cmd.js');
const devices = require('./lib/ui/devices.js');
const filmout = require('./lib/ui/filmout.js');
const mse = require('./lib/ui/mscript.js');
const capper = require('./lib/ui/capper.js');
const Mscript = require('./lib/mscript');
const { delay } = require('./lib/delay');
const alertObj = require('./lib/ui/alert.js');
let log;
@ -50,4 +53,6 @@ async function init () {
proj.init();
cam.init();
seq.init();
capper.init();
alertObj.init();
};

40
app/src/lib/ui/alert.ts Normal file
View File

@ -0,0 +1,40 @@
'use strict';
/// <reference path ="jquery.d.ts"/>
declare var uuid : any;
declare var ipcRenderer : any;
let alertObj : Alert;
class Alert {
id : string = 'alert';
constructor () {
}
public init () {
this.listen();
}
public start (msg : string) {
alert(msg);
this.end();
}
private end () {
const obj : any = {};
ipcRenderer.sendSync(this.id, obj);
}
private listen () {
ipcRenderer.on(this.id, (function (event : Event, arg : any) {
this.start(arg.msg);
}).bind(this));
};
}
alertObj = new Alert();
module.exports = alertObj;

96
app/src/lib/ui/capper.ts Normal file
View File

@ -0,0 +1,96 @@
'use strict';
/// <reference path ="jquery.d.ts"/>
declare var uuid : any;
declare var ipcRenderer : any;
declare var w2ui : any;
let capper : Capper;
interface CapperEvent {
id : string;
state : boolean;
callback? : Function;
}
class Capper {
public enabled = false;
queue : any = {};
lock : boolean = false;
id : string = 'capper';
state : boolean = false;
constructor () {
}
init () {
this.listen();
}
public enable () {
$('.black').addClass('on');
$('#cmd_black_forward').parent().removeClass('hide');
$('#cmd_black_backward').parent().removeClass('hide');
$('#cmd_capper_on').parent().removeClass('hide');
$('#cmd_capper_off').parent().removeClass('hide');
this.enabled = true;
}
public capper (state : boolean, callback : Function) {
let obj : CapperEvent;
if (this.lock) {
return false;
}
obj = {
state,
id : uuid()
};
ipcRenderer.sendSync(this.id, obj);
if (typeof callback !== 'undefined') {
obj.callback = callback;
}
this.queue[obj.id] = obj;
this.lock = true;
this.state = state;
if (state) {
$('#cmd_capper_on').addClass('active');
$('#cmd_capper_off').removeClass('active');
} else {
$('#cmd_capper_off').addClass('active');
$('#cmd_capper_on').removeClass('active');
}
}
public end (c : string, id : string, ms : number) {
if (c === cfg.arduino.cmd.capper_on) {
this.state = true;
} else if (c === cfg.arduino.cmd.capper_off) {
this.state = false;
}
if (typeof this.queue[id] !== 'undefined') {
if (typeof this.queue[id].callback !== 'undefined') {
this.queue[id].callback(ms);
}
delete this.queue[id];
this.lock = false;
}
}
private listen () {
ipcRenderer.on(this.id, function (event : Event, arg : any) {
capper.end(arg.cmd, arg.id, arg.ms);
return event.returnValue = true;
});
};
}
capper = new Capper();
module.exports = capper;

View File

@ -82,12 +82,6 @@ class Devices {
//devices.profile(arg.profile)
}
seq.set(0, cfg.cmd.camera_forward);
seq.set(1, cfg.cmd.projector_forward);
grid.state(0);
grid.state(1);
seq.stats();
if (arg.projector_second) {
//add second row of projector pads to grid
proj.second.enable();
@ -96,6 +90,17 @@ class Devices {
//add second row of camera pads to grid
cam.second.enable();
}
if (arg.capper) {
//add capper features to grid
capper.enable();
}
seq.set(0, cfg.cmd.camera_forward);
seq.set(1, cfg.cmd.projector_forward);
grid.state(0);
grid.state(1);
seq.stats();
return event.returnValue = true;
}

View File

@ -19,6 +19,9 @@ let grid : Grid;
*******/
class Grid {
private swatchesElem : any = {};
private projector_cmds : string[] = [
'PF', 'PB', 'P2F', 'P2B', 'PPF', 'PPB'
];
constructor () {
}
@ -40,8 +43,9 @@ class Grid {
const step : Step = seq.grid[x];
let className : string;
let className2 : string;
elem.prop('checked', false);
if (typeof step !== 'undefined') {
elem.prop('checked', false);
if (step.cmd === cfg.cmd.cameras_forward) {
className = cfg.cmd.camera_forward;
className2 = cfg.cmd.camera_second_forward;
@ -67,6 +71,12 @@ class Grid {
} else if (step.cmd === cfg.cmd.projector_backward_projector_second_forward) {
className = cfg.cmd.projector_backward;
className2 = cfg.cmd.projector_second_forward;
} else if (step.cmd === cfg.cmd.black_forward) {
className = cfg.cmd.camera_forward;
className2 = 'black';
} else if (step.cmd === cfg.cmd.black_backward) {
className = cfg.cmd.camera_backward;
className2 = 'black';
} else {
className = step.cmd;
}
@ -80,12 +90,17 @@ class Grid {
lightElem.css('background', `rgb(${step.light})`)
.addClass('a')
.prop('title', `rgb(${seq.light})`);
} else {
lightElem.css('background', 'transparent')
.removeClass('a')
.prop('title', '');
}
if (capper.enabled && this.projector_cmds.indexOf(step.cmd) !== -1) {
$(`.black[x=${x}]`).addClass('disabled');
} else if (capper.enabled) {
$(`.black[x=${x}]`).removeClass('disabled');
}
} else {
lightElem.css('background', 'transparent')
.removeClass('a')
@ -123,6 +138,7 @@ class Grid {
'camera_second_backward',
'projector_backward',
'projector_second_backward',
'black',
'light_set',
'numbers'
];
@ -141,6 +157,9 @@ class Grid {
} else if (cmds[i] === 'light_set') {
elem = `<div x="${x}" class="L"></div>`
$(cmd).append($(elem));
} else if (cmds[i] === 'black') {
elem = `<input type="checkbox" x="${x}" class="black" />`;
$(cmd).append($(elem));
} else {
elem = `<input type="checkbox" x="${x}" />`;
$(cmd).append($(elem).addClass(cfg.cmd[cmds[i]]));
@ -169,7 +188,20 @@ class Grid {
current = seq.grid[x].cmd + ''; // cast to string, bad hack
}
if (checked) {
if (cam.second.enabled && current.indexOf('C') !== -1) {
if (c.indexOf('black') !== -1) {
if (other === '') {
c = cfg.cmd.black_forward;
} else if (current.indexOf('C') !== -1) {
if (other == cfg.cmd.camera_forward) {
c = cfg.cmd.black_forward;
} else if (other === cfg.cmd.camera_backward) {
c = cfg.cmd.black_backward;
}
} else if (current.indexOf('P') !== -1) {
$(elem).prop('checked', false);
return;
}
} else if (cam.second.enabled && current.indexOf('C') !== -1) {
if (c === cfg.cmd.camera_forward) {
if (other === cfg.cmd.camera_second_forward) {
c = cfg.cmd.cameras_forward;
@ -197,7 +229,6 @@ class Grid {
}
} else if (proj.second.enabled && current.indexOf('P') !== -1) {
if (c === cfg.cmd.projector_forward) {
if (current === cfg.cmd.projectors_backward) {
c = cfg.cmd.projector_forward_projector_second_backward;
} else if (current === cfg.cmd.projector_backward_projector_second_forward) {
@ -208,7 +239,6 @@ class Grid {
c = cfg.cmd.projector_forward_projector_second_backward;
}
} else if (c === cfg.cmd.projector_backward) {
if (current === cfg.cmd.projectors_forward) {
c = cfg.cmd.projector_backward_projector_second_forward;
} else if (current === cfg.cmd.projector_forward_projector_second_backward) {
@ -219,7 +249,6 @@ class Grid {
c = cfg.cmd.projectors_backward;
}
} else if (c === cfg.cmd.projector_second_forward) {
if (current === cfg.cmd.projectors_backward) {
c = cfg.cmd.projector_backward_projector_second_forward;
} else if (current === cfg.cmd.projector_forward_projector_second_backward) {
@ -230,7 +259,6 @@ class Grid {
c = cfg.cmd.projector_backward_projector_second_forward;
}
} else if (c === cfg.cmd.projector_second_backward) {
if (current === cfg.cmd.projectors_forward) {
c = cfg.cmd.projector_forward_projector_second_backward;
} else if (current === cfg.cmd.projector_backward_projector_second_forward) {
@ -244,7 +272,22 @@ class Grid {
}
seq.set(x, c);
} else {
if (cam.second.enabled && current.indexOf('C') !== -1) {
if (c.indexOf('black') !== -1) {
if (current === 'BF' || current === 'BB') {
if (other === cfg.cmd.camera_forward) {
c = cfg.cmd.camera_forward;
} else if (other === cfg.cmd.camera_backward) {
c = cfg.cmd.camera_backward;
}
} else if (current.indexOf('P') !== -1) {
$(elem).prop('checked', false);
return;
}
} else if (other === 'black' && current === cfg.cmd.camera_forward) {
c = '';
} else if (other === 'black' && current === cfg.cmd.camera_backward) {
c = '';
} else if (cam.second.enabled && current.indexOf('C') !== -1) {
if (current === cfg.cmd.cameras_forward) {
if (other === cfg.cmd.camera_second_forward) {
c = cfg.cmd.camera_second_forward;

321
app/src/lib/ui/mscript.ts Normal file
View File

@ -0,0 +1,321 @@
'use strict';
/// <reference path ="jquery.d.ts"/>
import Mscript from 'mscript';
declare var nav : any;
declare var gui : any;
declare var CodeMirror : any;
declare var mscript : any;
declare var cmd : any;
interface MSE {
mscript : MscriptGUI,
console : MscriptConsole
}
/******
Mscript GUI
*******/
class MscriptGUI {
public editor : any = {};
public data : any = {};
public raw : string = '';
constructor () {
}
/**
* Initializes the mscript GUI. Sets up CodeMirror instance,
* binds events and sets height of editor.
**/
public init () {
const startingScript : string = `CF 1
PF 1`;
const editorHeight : number = $(window).height() - $('footer').eq(0).height() - 30;
const editorElem : HTMLTextAreaElement = document.getElementById('editor') as HTMLTextAreaElement;
const editorConfig : any = {
lineNumbers: true,
mode: 'python',
matchBrackets: true,
theme: 'monokai'
};
$('#editor').val(startingScript);
this.editor = CodeMirror.fromTextArea(editorElem, editorConfig);
this.editor.setSize(null, editorHeight);
this.editor.on('change', (e : Event) => { });
$(document).on('resize', function (e : Event) {
this.editor.setSize(null, editorHeight);
}.bind(this));
}
/**
* Callback for when open event occurs.
**/
public open () {
//recalcuate in case resize has occurred needed
const editorHeight : number = $(window).height() - $('footer').eq(0).height() - 30;
this.editor.setSize(null, editorHeight);
this.editor.refresh();
}
/**
* Create script from the sequencer's current state.
* Previous comment: ehhhh
* TODO: Make this smarter.
**/
fromSequence () {
let str : string;
let tmp : any[] = [];
let cont : boolean;
let cmd : string;
//str = seq.grid.map(step => { return step.cmd }).join('\n'); //quick hack
//console.dir(seq.grid);
for (let step of seq.grid) {
if (!step || !step.cmd) {
continue;
}
cmd = step.cmd;
if (tmp.length > 0 && tmp[tmp.length - 1].cmd === cmd) {
tmp[tmp.length - 1].num++;
continue;
}
tmp.push({ cmd, num : 1 });
}
tmp = tmp.map(line => {
return `${line.cmd} ${line.num}`
})
if (seq.gridLoops > 1) {
tmp.map(line => {
return ` ${line}`;
})
tmp.reverse();
tmp.push(`LOOP ${seq.gridLoops}`);
tmp.reverse();
tmp.push('END');
}
str = tmp.join('\n');
nav.change('script');
cont = confirm(`Are you sure you want to over-write the current sequence?`);
if (cont) {
this.editor.getDoc().setValue(str);
}
}
/**
* Take current compiled mscript state and send it to the sequencer
* GUI. TODO: Add confirm step if sequence is longer than X steps.
* TODO: Make this smarter (detect outer non-fade loop and assign to loop counter)
**/
toGUI () {
let c : string;
let step : string;
for (let x : number = 0; x < this.data.arr.length; x++) {
c = this.data.arr[x];
seq.set(x, c);
if (c === 'CF' || c === 'CB') {
if (typeof this.data.meta[x] !== 'undefined' && this.data.meta[x] !== '') {
seq.setLight(x, this.data.meta[x]);
} else {
seq.setLight(x, light.color);
}
} else {
//unset light?
}
grid.state(x);
}
}
/**
* Handles compilation of mscript and switches to sequencer
* GUI after confirmation questions.
**/
toSequence () {
const data : string = this.editor.getValue();
let cont : boolean = false;
if (data !== this.raw) {
cont = confirm(`Current script has not been compiled. Compile first?`);
if (cont) {
this.compile()
}
}
mse.console.print(`Sending compiled script to GUI sequencer...`);
seq.clear();
this.toGUI();
grid.refresh();
seq.stats();
return nav.change('sequencer');
}
/**
* Compiles text in editor using the Mscript library.
*
**/
compile () {
const data : string = this.editor.getValue();
const mscript : Mscript = new Mscript();
const output : any = mscript.interpret(data);
const len : number = output.arr.length;
const cam2 : string = typeof output.cam2 !== 'undefined' ? `, CAM2 : ${output.cam2}` : '';
const proj2 : string = typeof output.proj2 !== 'undefined' ? `, PROJ2 : ${output.proj2}` : '';
const report : string = `Sequence contains ${len} step${(len === 1 ? '' : 's')}, CAM: ${output.cam}, PROJ: ${output.proj}${cam2}${proj2}`;
this.raw = data;
this.data = output;
//mse.console.print(JSON.stringify(output, null, '\t') + '\n')
mse.console.print(report);
}
/**
* This function re-writes the optional "meta" attribute
* of an mcopy command object to "light". TODO: change this.
* Do not re-write this object and improve the consumers
* of the compiled data.
**/
prepare () {
const arr : any[] = [];
let obj : any;
for (let i : number = 0; i < this.data.arr.length; i++) {
obj = {
cmd : this.data.arr[i]
};
if (typeof this.data.meta[i] !== 'undefined' && this.data.meta[i] !== '') {
obj.light = this.data.meta[i];
} else {
obj.light = light.color.join(',');
}
arr.push(obj);
}
return arr;
}
/**
* Method which compiles script if needs and then runs as a sequence.
**/
run () {
const data : string = this.editor.getValue();
let arr : any[];
let cont : boolean = false;
if (data !== this.raw) {
cont = confirm(`Current script has not been compiled. Compile first?`);
if (cont) {
this.compile();
}
}
arr = this.prepare();
mse.console.print(`Started running compiled sequence...`);
gui.overlay(true);
gui.spinner(true, `Running mscript sequence...`, true, true);
return seq.exec(arr, 1);
}
}
/*******
* Mscript GUI Console
*******/
class MscriptConsole {
public elem : JQuery;
private lines : string[];
/**
* Initializes the console by creating the element
* containing the output text and binding to
* keyup event.
**/
public init () {
this.elem = $('#console textarea');
this.elem.on('keyup', function (e : KeyboardEvent) {
var code : number = e.keyCode || e.which;
if (code === 13) {
this.exec();
e.preventDefault();
return false;
}
}.bind(this));
}
/**
* Parse the current state of the console and get the last
* line to add to the current state array.
**/
parse () {
const lines : string[] = (this.elem.val() + '').split('\n');
const line : string = lines[lines.length - 2].replace('>', '').trim();
this.lines.push(line);
}
/**
* Executes the command in the last line of the console.
* TODO: implement the remaining commands. Currently only camera
* forward and backward will be executed.
**/
exec () {
let command : string;
this.parse();
command = this.lines[this.lines.length - 1].replace('>', '').trim();
log.info(command);
this.newLine();
if (mscript.cmd.indexOf(command) !== -1) {
if (command === 'CF') {
cmd.camera_forward(light.color);
} else if (cmd === 'CB') {
cmd.camera_backward(light.color);
}
}
if (command === 'compile') {
mse.mscript.compile();
} else if (command === 'run') {
mse.mscript.run();
}
}
/**
* Adds a new line to the console after an event
* and re-establishes the height of the array. Animates
* the console to scroll down to last line.
**/
newLine () {
let current : string = (this.elem.val() + '');
let height : number;
current += '> ';
this.elem.val(current);
height = this.elem[0].scrollHeight;
this.elem.animate({
scrollTop : height
}, 'normal');
}
/**
* Print string to the console and add new line
**/
print (str : string) {
let current : string = (this.elem.val() + '');
let height : number;
current += str;
current += '\n';
mse.console.elem.val(current);
mse.console.elem.focus();
this.newLine();
}
}
const mse : MSE = {
mscript : new MscriptGUI(),
console : new MscriptConsole()
};
module.exports = mse;

View File

@ -71,11 +71,21 @@ class Sequence {
log.info('Sequence stopped', 'SERIAL', true);
timeStr = ( arg.ms < 2000 ) ? `${arg.ms}ms` : humanizeDuration(arg.ms);
gui.notify(`SEQUENCE`, `Sequence finished in ${timeStr}`);
if (capper.enabled && this.arr.some(this.hasCapper)) {
$('#cmd_capper_off').addClass('active');
$('#cmd_capper_on').removeClass('active');
}
}
}
return event.returnValue = true;
}
private hasCapper (el : any) {
if (['BF', 'BB'].indexOf(el.cmd) !== -1) {
return true;
}
}
private progress (step : number, loop : number) {
const elem : any = $('.progress-bar');
const len : number = this.arr.length;

View File

@ -258,6 +258,8 @@ CF 10`
})
})
//secondary
/*describe('mscript - Variables', () => {
const script1 =
`@LIGHT=200,200,200

View File

@ -11,7 +11,8 @@
"outDir": "./",
"rootDir" : "./src/",
"paths" : {
"log" : ["./lib/log"]
"log" : ["./lib/log"],
"mscript" : ["./lib/mscript"]
}
},
"exclude" : [

View File

@ -1,5 +1,5 @@
{
"version": "1.7.0",
"version": "1.7.1",
"ext_port": 1111,
"profiles": {
"mcopy": {
@ -15,8 +15,8 @@
"momentary": 0
},
"black": {
"before": 0,
"after": 0
"before": 100,
"after": 100
},
"light": false
},
@ -178,7 +178,15 @@
"cameras": "4",
"camera_projectors_identifier": "5",
"cameras_projector_identifier": "6",
"cameras_projectors_identifier": "7"
"cameras_projectors_identifier": "7",
"capper_identifier": "C",
"camera_capper_identifier": "8",
"camera_capper_projector_identifier": "9",
"camera_capper_projectors_identifier": "0",
"capper_on": "A",
"capper_off": "B",
"takeup_forward" : "D",
"takeup_backward" : "E"
}
}
}

Binary file not shown.

View File

@ -0,0 +1,156 @@
#include <Servo.h>
boolean debug_state = false;
/*
----------------------------------------------------
Servo - Arduino
-
Red - 5V
Black - GND
Yellow - PWM Pin (9 in this example)
Using TowerPro SG-5010 - default angle 93
TowerPro MG-995 - default angle 93
as servos for development
----------------------------------------------------
*/
/* ------------------------------------------------
* pins
* ------------------------------------------------*/
//Arduino Duemilanove +
//Arduino Uno
const int PIN_SERVO = 6;
volatile boolean running = false;
volatile boolean cap_state = false;
volatile int angle = 0;
const int cap_on_angle = 153; // tune this variable to your servo
const int cap_off_angle = 93; // -60 degrees apart
volatile long timer = 0;
volatile int current_angle = 0;
const char cmd_cap_on = 'A';
const char cmd_cap_off = 'B';
const char cmd_debug = 'd';
const char cmd_connect = 'i';
volatile char cmd_char = 'z';
const char cmd_mcopy_identifier = 'm';
const char cmd_capper_identifier = 'C';
const int serialDelay = 5;
Servo servo;
//SG-5010 speed 0.18s / 60 degree
//
//converted to milliseconds/angle
const float servoSpeed = 400.0 / 60.0;
void setup() {
Serial.begin(57600);
Serial.flush();
Serial.setTimeout(serialDelay);
Pins_init();
Servo_init();
}
void loop() {
if (Serial.available()) {
/* read the most recent byte */
cmd_char = (char)Serial.read();
}
if (cmd_char != 'z') {
cmd(cmd_char);
cmd_char = 'z';
}
timer = millis();
}
void cmd (char val) {
if (val == cmd_debug) {
debug();
} else if (val == cmd_connect) {
connect();
} else if (val == cmd_mcopy_identifier) {
identify();
} else if (val == cmd_cap_on) {
Cap_on(false, false);
} else if (val == cmd_cap_off) {
Cap_off(false, false);
}
}
void debug () {
debug_state = true;
Serial.println(cmd_debug);
log("debugging enabled");
}
void connect () {
Serial.println(cmd_connect);
log("connect()");
}
void identify () {
Serial.println(cmd_capper_identifier);
log("identify()");
}
void Pins_init () {
//
}
void Servo_init () {
servo.attach(PIN_SERVO);
Cap_off(true, true);
}
void Servo_angle (int newAngle) {
servo.write(newAngle);
delay(Servo_delay(newAngle, angle) + 50);
angle = newAngle;
}
int Servo_delay (int angleA, int angleB) {
int angle = abs(angleA - angleB);
return (int) ceil((float) angle * servoSpeed);
}
void Cap_off (boolean suppress, boolean force) {
current_angle = servo.read();
if (cap_state || current_angle != cap_off_angle) {
Servo_angle(cap_off_angle);
cap_state = false;
} else {
log("Cap already off");
}
log("Cap_off()");
if (!suppress) {
Serial.println(cmd_cap_off);
}
}
void Cap_on (boolean suppress, boolean force) {
current_angle = servo.read();
if (!cap_state || current_angle != cap_on_angle) {
Servo_angle(cap_on_angle);
cap_state = true;
} else {
log("Cap already on");
}
log("Cap_on()");
if (!suppress) {
Serial.println(cmd_cap_on);
}
}
void log (String msg) {
if (debug_state) {
Serial.println(msg);
}
}

View File

@ -1,13 +1,14 @@
boolean debug_state = false;
const int proj_fwd_pin = 12;
const int proj_bwd_pin = 11;
const int proj_pin = 10;
const int proj_fwd_pin = 9;
const int proj_bwd_pin = 10;
const int proj_micro_pin = 4;
const int proj_time = 1200;
const int proj_delay = 42;
boolean proj_dir = true;
boolean proj_running = false;
volatile int proj_micro_raw;
const char cmd_projector = 'p';
const char cmd_proj_forward = 'g';
@ -25,6 +26,16 @@ void setup() {
Serial.begin(57600);
Serial.flush();
Serial.setTimeout(serialDelay);
pins_init();
}
void pins_init () {
pinMode(proj_fwd_pin, OUTPUT);
pinMode(proj_bwd_pin, OUTPUT);
pinMode(proj_micro_pin, INPUT_PULLUP);
analogWrite(proj_fwd_pin, 0);
analogWrite(proj_bwd_pin, 0);
}
void loop() {
@ -36,6 +47,9 @@ void loop() {
cmd(cmd_char);
cmd_char = 'z';
}
if (proj_running) {
proj_reading();
}
}
void cmd (char val) {
@ -72,11 +86,11 @@ void identify () {
void proj_start () {
if (proj_dir) {
digitalWrite(proj_fwd_pin, HIGH);
digitalWrite(proj_bwd_pin, LOW);
analogWrite(proj_fwd_pin, 255);
analogWrite(proj_bwd_pin, 0);
} else {
digitalWrite(proj_bwd_pin, HIGH);
digitalWrite(proj_fwd_pin, LOW);
analogWrite(proj_bwd_pin, 255);
analogWrite(proj_fwd_pin, 0);
}
proj_running = true;
delay(500); // Let bump pass out of microswitch
@ -95,8 +109,8 @@ void proj_reading () {
}
void proj_stop () {
digitalWrite(proj_bwd_pin, LOW);
digitalWrite(proj_fwd_pin, LOW);
analogWrite(proj_bwd_pin, 0);
analogWrite(proj_fwd_pin, 0);
proj_running = false;

View File

@ -0,0 +1,39 @@
#include <Servo.h>
const int PIN_SERVO = 6;
Servo servo;
/*
----------------------------------------------------
Servo - Arduino
-
Red - 5V
Black - GND
Yellow - PWM Pin (9 in this example)
Using TowerPro SG-5010 - default 93
TowerPro MG-995 -
as servos for development
----------------------------------------------------
*/
void setup() {
Serial.begin(57600);
Serial.flush();
Servo_init();
}
void loop() {
delay(1000);
servo.write(153);
delay(1000);
servo.write(93);
}
void Servo_init () {
servo.attach(PIN_SERVO);
int angle = servo.read();
Serial.print("Default angle: ");
Serial.println(angle);
}

View File

@ -0,0 +1,141 @@
volatile boolean DEBUG = true;
class ArriSMotor {
public:
int speed = 255;
int average = -1;
boolean direction = true;
boolean running = false;
boolean primed = false;
void Begin () {
pinMode(pinPositive, OUTPUT);
pinMode(pinNegative, OUTPUT);
pinMode(pinMicroswitch, INPUT_PULLUP);
}
void Start (boolean dir) {
startTime = millis();
rotationTime = startTime;
direction = dir;
rotations = 0;
Run(direction, speed);
running = true;
primed = false;
};
void Run (boolean dir, int speed) {
if (dir) {
analogWrite(pinPositive, 0);
analogWrite(pinNegative, speed);
} else {
analogWrite(pinPositive, speed);
analogWrite(pinNegative, 0);
}
}
void CheckMicroswitch () {
int value = digitalRead(pinMicroswitch);
if (value == 1) {
if (running && !primed && millis() - rotationTime > primeTime) {
primed = true;
}
}
if (value == 0) {
if (running && primed && millis() - rotationTime > minTime) {
if (rotations < rotationsPer - 1) {
rotations++;
primed = false;
rotationTime = millis();
} else {
Stop();
}
}
}
};
private:
const int pinPositive = 5;
const int pinNegative = 6;
const int pinMicroswitch = 7;
const int rotationsPer = 3;
volatile int rotations = 0;
volatile long startTime = 0;
volatile long rotationTime = 0;
const int primeTime = 100;
const int minTime = 200;
void Stop () {
int val = 1;
digitalWrite(pinPositive, LOW);
digitalWrite(pinNegative, LOW);
EvaluateTiming();
Run(!direction, 40);
long c = millis();
while (val == 1) {
delay(4);
val = digitalRead(pinMicroswitch);
}
Serial.print("Correction: ");
Serial.print(millis() - c);
Serial.println("ms");
digitalWrite(pinPositive, LOW);
digitalWrite(pinNegative, LOW);
running = false;
primed = false;
}
void EvaluateTiming () {
long ms = millis() - startTime;
if (ms < 0) {
return;
}
if (average == -1) {
average = ms;
} else {
average = round(( ms + average ) / 2);
}
if (DEBUG) {
Serial.print("Frame: ");
Serial.print(ms);
Serial.println("ms");
Serial.print("Average: ");
Serial.print(average);
Serial.println("ms");
}
}
};
ArriSMotor motor;
void setup() {
Serial.begin(57600);
motor.Begin();
}
boolean d = false;
int count = 0;
void loop() {
if (!motor.running) {
delay(5000);
motor.Start(d);
count++;
if (count > 9) {
d = !d;
count = 0;
}
}
motor.CheckMicroswitch();
if (!motor.primed) {
delay(1);
}
}

View File

@ -0,0 +1,117 @@
#include <Adafruit_MotorShield.h>
volatile boolean debug_state = true;
volatile boolean cam_dir = true;
volatile boolean running = true;
const int stepsPerRevolution = 200;
const int fullRotation = 3 * stepsPerRevolution;
const int openRotationForward = 300;
const int openRotationBackward = 300;
//CAMERA COMMANDS
const char cmd_camera = 'c';
const char cmd_cam_forward = 'e';
const char cmd_cam_backward = 'f';
const char cmd_debug = 'd';
const char cmd_connect = 'i';
volatile char cmd_char = 'z';
const char cmd_mcopy_identifier = 'm';
const char cmd_cam_identifier = 'k';
const int serialDelay = 5;
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
//Set up for a 200step motor (NEMA 17)
Adafruit_StepperMotor *stepper = AFMS.getStepper(stepsPerRevolution, 2);
void setupMotor () {
//TWBR = ((F_CPU /400000l) - 16) / 2; // Change the i2c clock to 400KHz
if (!AFMS.begin()) { // default frequency 1.6KHz
log("Could not find Motor Shield. Check wiring.");
while (1);
}
log("Motor Shield found.");
stepper->setSpeed(600);
}
void setup() {
Serial.begin(57600);
setupMotor();
}
void loop() {
if (Serial.available()) {
// read the most recent byte
cmd_char = (char)Serial.read();
}
if (cmd_char != 'z') {
cmd(cmd_char);
cmd_char = 'z';
}
}
void cmd (char val) {
if (val == cmd_debug) {
debug();
} else if (val == cmd_connect) {
connect();
} else if (val == cmd_mcopy_identifier) {
identify();
} else if (val == cmd_cam_forward) {
setDir(true); //explicit
} else if (val == cmd_cam_backward) {
setDir(false);
} else if (val == cmd_camera) {
cam();
}
}
void debug () {
debug_state = true;
Serial.println(cmd_debug);
log("debugging enabled");
}
void connect () {
Serial.println(cmd_connect);
log("connect()");
}
void identify () {
Serial.println(cmd_cam_identifier);
log("identify()");
}
void setDir (boolean dir) {
cam_dir = dir;
if (cam_dir) {
Serial.println(cmd_cam_forward);
log("setDir = true");
} else {
Serial.println(cmd_cam_backward);
log("setDir -> false");
}
}
void cam () {
long startTime = millis();
if (cam_dir) {
stepper->step(fullRotation, FORWARD, DOUBLE);
Serial.println(cmd_cam_forward);
log("cam -> forward");
} else {
stepper->step(fullRotation, BACKWARD, DOUBLE);
Serial.println(cmd_cam_backward);
log("cam -> backward");
}
log(String(millis() - startTime));
}
void log (String msg) {
if (debug_state) {
Serial.println(msg);
}
}

View File

@ -0,0 +1,260 @@
/**
* This is a specialized version of the mcopy firmware for
* controlling the JK104-R/Bolex camera of the optical printer
* at MONO NO AWARE. This uses a Sainsmart 8 Solid State Relay
* board wired into the directional switches of a JK104-R/Bolex camera
* controller box, a secondary projector controller box and it
* runs on an Arduino Uno compatible board.
*
* 7/17/2022
*
* This firmware has been modified to include an optional capper element.
*
* Pins
* 12 - CH1 - BWD CAM 1
* 11 - CH2 - FWD CAM 1 (bridged to CH1)
* 10 - CH3 - BWD CAM 1
* 09 - CH4 - FWD CAM 1 (bridged to CH3)
* 08 - CH5 - BWD CAM 1
* - controls the directional relays of the Bolex Camera.
* 07 - CH8 - 4 pronged trigger cable
* - triggers the camera
*
* 06 - SIGNAL - Capper servo signal
* 05 - GND - Closed circuit to GND in cable to detect capper is attached.
*/
#include <Servo.h>
boolean debug_state = false;
Servo servo;
const int cam_bwd_pin_1 = 12;
const int cam_fwd_pin_1 = 11;
const int cam_bwd_pin_2 = 10;
const int cam_fwd_pin_2 = 9;
const int cam_bwd_pin_3 = 8;
const int cam_pin = 7;
const int capper_pin = 6; //servo
const int capper_exists_pin = 5;
const int cam_momentary = 60;
const int cam_time = 600; //secondary projector speed
const int cam_delay = 42;
volatile boolean cam_dir = true;
volatile boolean cam_running = false;
volatile boolean capper_exists = false;
volatile boolean capper_state = false;
volatile int capper_angle = 0;
const int capper_on_angle = 153; // tune this variable to your servo
const int capper_off_angle = 93; // -60 degrees apart
//SG-5010 speed 0.18s / 60 degree
//
//converted to milliseconds/angle
const float servo_speed = 400.0 / 60.0;
const char cmd_camera = 'c';
const char cmd_cam_forward = 'e';
const char cmd_cam_backward = 'f';
const char cmd_debug = 'd';
const char cmd_connect = 'i';
volatile char cmd_char = 'z';
const char cmd_mcopy_identifier = 'm';
const char cmd_cam_identifier = 'k';
const char cmd_camera_capper_identifier = '8';
const char cmd_capper_on = 'A';
const char cmd_capper_off = 'B';
const int serialDelay = 5;
void setup() {
Serial.begin(57600);
Serial.flush();
Serial.setTimeout(serialDelay);
pinMode(cam_fwd_pin_1, OUTPUT);
pinMode(cam_bwd_pin_1, OUTPUT);
pinMode(cam_fwd_pin_2, OUTPUT);
pinMode(cam_bwd_pin_2, OUTPUT);
pinMode(cam_bwd_pin_3, OUTPUT);
pinMode(cam_pin, OUTPUT);
pinMode(capper_exists_pin, INPUT_PULLUP);
digitalWrite(cam_pin, LOW);
digitalWrite(cam_fwd_pin_1, HIGH);
digitalWrite(cam_fwd_pin_2, HIGH);
digitalWrite(cam_bwd_pin_1, LOW);
digitalWrite(cam_bwd_pin_2, LOW);
digitalWrite(cam_bwd_pin_3, LOW);
capper_init();
}
void loop() {
if (Serial.available()) {
/* read the most recent byte */
cmd_char = (char)Serial.read();
}
if (cmd_char != 'z') {
cmd(cmd_char);
cmd_char = 'z';
}
}
void cmd (char val) {
if (val == cmd_debug) {
debug();
} else if (val == cmd_connect) {
connect();
} else if (val == cmd_mcopy_identifier) {
identify();
} else if (val == cmd_camera) {
camera();
} else if (val == cmd_cam_forward) {
cam_direction(true);
} else if (val == cmd_cam_backward) {
cam_direction(false);
} else if (capper_exists && val == cmd_capper_on) {
capper_on(false, false);
} else if (capper_exists && val == cmd_capper_off) {
capper_off(false, false);
}
}
void debug () {
debug_state = true;
Serial.println(cmd_debug);
log("debugging enabled");
}
void connect () {
Serial.println(cmd_connect);
log("connect()");
}
void identify () {
if (capper_exists) {
Serial.println(cmd_camera_capper_identifier);
} else {
Serial.println(cmd_cam_identifier);
}
log("identify()");
}
void camera () {
if (!cam_running) {
cam_running = true;
digitalWrite(cam_pin, HIGH);
delay(cam_momentary);
digitalWrite(cam_pin, LOW);
delay(cam_time - cam_momentary + cam_delay);
Serial.println(cmd_camera);
log("camera()");
cam_running = false;
}
}
void cam_direction (boolean state) {
cam_dir = state;
digitalWrite(cam_fwd_pin_1, LOW);
digitalWrite(cam_fwd_pin_2, LOW);
digitalWrite(cam_bwd_pin_1, LOW);
digitalWrite(cam_bwd_pin_2, LOW);
digitalWrite(cam_bwd_pin_3, LOW);
if (state) {
digitalWrite(cam_fwd_pin_1, HIGH);
digitalWrite(cam_fwd_pin_2, HIGH);
Serial.println(cmd_cam_forward);
log("cam_direction -> true");
} else {
digitalWrite(cam_bwd_pin_1, HIGH);
digitalWrite(cam_bwd_pin_2, HIGH);
digitalWrite(cam_bwd_pin_3, HIGH);
Serial.println(cmd_cam_backward);
log("cam_direction -> false");
}
//delay(50); //delay after direction change to account for slippage of the belt
}
boolean does_capper_exist () {
boolean exists = false;
if (digitalRead(capper_exists_pin) == 0) {
exists = true;
}
return exists;
}
void capper_init () {
capper_exists = does_capper_exist();
if (capper_exists) {
log("Capper exists");
servo.attach(capper_pin);
capper_off(true, true);
}
}
void set_capper_angle (int newAngle) {
int delay_time = get_capper_delay(newAngle, capper_angle) + 50;
servo.write(newAngle);
delay(delay_time);
capper_angle = newAngle;
}
int get_capper_delay (int angleA, int angleB) {
int range = abs(angleA - angleB);
return (int) ceil((float) range * servo_speed);
}
void capper_off (boolean suppress, boolean force) {
int current_angle = servo.read();
if (capper_state || current_angle != capper_off_angle) {
set_capper_angle(capper_off_angle);
capper_state = false;
} else {
log("Capper already off");
}
log("cap_off()");
if (!suppress) {
Serial.println(cmd_capper_off);
}
}
void capper_on (boolean suppress, boolean force) {
int current_angle = servo.read();
if (!capper_state || current_angle != capper_on_angle) {
set_capper_angle(capper_on_angle);
capper_state = true;
} else {
log("Capper already on");
}
log("capper_on()");
if (!suppress) {
Serial.println(cmd_capper_on);
}
}
void log (String msg) {
if (debug_state) {
Serial.println(msg);
}
}

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "mcopy",
"version": "1.7.0",
"version": "1.7.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "mcopy",
"version": "1.7.0",
"version": "1.7.1",
"license": "MIT",
"dependencies": {
"arduino": "file:app/lib/arduino",

View File

@ -1,6 +1,6 @@
{
"name": "mcopy",
"version": "1.7.0",
"version": "1.7.1",
"description": "Small gauge film optical printer platform",
"main": "build.js",
"directories": {

View File

@ -1,5 +1,5 @@
{
"version": "1.6.9",
"version": "1.7.1",
"ext_port": 1111,
"profiles": {
"mcopy": {
@ -15,8 +15,8 @@
"momentary": 0
},
"black": {
"before": 0,
"after": 0
"before": 100,
"after": 100
},
"light": false
},
@ -178,7 +178,13 @@
"cameras": "4",
"camera_projectors_identifier": "5",
"cameras_projector_identifier": "6",
"cameras_projectors_identifier": "7"
"cameras_projectors_identifier": "7",
"capper_identifier": "C",
"camera_capper_identifier": "8",
"camera_capper_projector_identifier": "9",
"camera_capper_projectors_identifier": "0",
"capper_on": "A",
"capper_off": "B"
}
}
}

488
scad/arri_s.scad Normal file
View File

@ -0,0 +1,488 @@
// Arri-S Animation Motor
include <./common.scad>;
include <./takeup.scad>;
include <./bellows.scad>;
BarrelDiameter = 45;
BarrelLength = 52;
SeatDiameter = 20;
SeatLength = 5.8;
CapLength = 19;
CapDiameter = 40;
CapThickness = 3;
CapCatchDiameter = 38;
CapCatchLength = 2;
CapCatchOffset = 15 + 1;
CapRimDiameter = 46.5;
CapRimThickness = 3;
NotchDiameter = 2;
NotchOffset = 3;
DriveLength = 7;
DriveDiameter1 = 11;
DriveDiameter2 = 9;
ShaftLength = 2.75;
ShaftDiameter = 5;
MicroswitchCompression = 8.7 - 6.9; //min
BearingDiameter = 22.5;
BearingInnerDiameter = 11.5;
capM3OffsetZ = 11.5;
PART = "none";
module motorBarrel () {
$fn = 200;
cylinder(r = R(BarrelDiameter), h = BarrelLength, center = true);
}
module motorSeat () {
$fn = 120;
cylinder(r = R(SeatDiameter), h = SeatLength, center = true);
}
module motorShaft () {
cylinder(r = R(ShaftDiameter), h = ShaftLength, center = true);
}
module motorDrive () {
cylinder(r = R(DriveDiameter1), h = DriveLength, center = true);
}
module motorOriginal () {
motorBarrel();
translate([0, 0, (BarrelLength / 2) + (SeatLength / 2)]) motorSeat();
//notch
$fn = 50;
translate([BarrelDiameter / 2, 0, -(BarrelLength / 2) + NotchOffset]) {
rotate([0, 90, 0]) {
cylinder(r = R(NotchDiameter), h = 1, center = true);
translate([0, 0, NotchDiameter / 4]) sphere(r = R(NotchDiameter));
}
}
translate([0, 0, (BarrelLength / 2) + (SeatLength) + (ShaftLength / 2)]) motorShaft();
translate([0, 0, (BarrelLength / 2) + (SeatLength) + (ShaftLength) + (DriveLength / 2)]) motorDrive();
}
module bodyCap () {
$fn = 200;
difference () {
cylinder(r = R(CapDiameter), h = CapLength, center = true);
cylinder(r = R(CapDiameter - CapThickness), h = CapLength + 1, center = true);
//catch
translate([0, 0, (CapLength / 2) - CapCatchOffset]) difference () {
cylinder(r = R(CapDiameter + 1), h = CapCatchLength, center = true);
cylinder(r = R(CapCatchDiameter), h = CapCatchLength + 1, center = true);
}
}
translate([0, 0, (CapLength / 2) + (CapRimThickness / 2)]) {
difference () {
cylinder(r = R(CapRimDiameter), h = CapRimThickness, center = true);
}
}
}
module bodyCapBellowsAdapter () {
$fn = 200;
difference () {
bodyCap();
translate([0, 0, (CapLength / 2) + (CapRimThickness / 2)]) {
cube([CapDiameter - CapThickness - 16, CapDiameter - CapThickness - 16, CapRimThickness + 1], center = true);
}
}
translate([0, 0, 16]) {
difference() {
cylinder(r = 37.9 / 2, h = 7, center = true);
cylinder(r = 30 / 2, h = 7 + 1, center = true);
}
}
}
/**
** Stepper Motor Design
**/
module animationMotorBodyPositive () {
difference () {
motorBarrel();
//hollow out
translate([0, 0, 4]) cylinder(r = R(BarrelDiameter) - 5, h = BarrelLength, center = true, $fn = 200);
//cut
translate([0, 0, 40]) cube([100, 100, BarrelLength], center = true);
cylinder(r = R(23), h = BarrelLength + 1, center = true, $fn = 100);
//window
translate([0, (BarrelDiameter / 2) - 2, -5]) cube([8, 20, 42], center = true);
}
//rim
translate([0, 0, -(BarrelLength / 2) - (3 / 2)]) {
difference () {
cylinder(r = R(BarrelDiameter) + 2, h = 3, center = true, $fn = 200);
cylinder(r = R(23), h = 3 + 1, center = true, $fn = 100);
}
}
//motor pad
translate([0, 0, -(BarrelLength / 2) - (3) - (4 / 2)]) {
difference () {
union () {
cube([42, 42, 4], center = true);
cylinder(r = R(BarrelDiameter) + 2, h = 4, center = true, $fn = 200);
}
cylinder(r = R(23), h = 4 + 1, center = true, $fn = 100);
for (i = [0 : 3]) {
rotate([0, 0, (i * 90) + 45]) translate([29.7, 0, 0]) cube([5.5, 5.5, 4 + 1], center = true);
}
}
}
//notch
$fn = 50;
rotate([0, 0, 35]) {
translate([BarrelDiameter / 2, 0, -(BarrelLength / 2) + NotchOffset]) {
rotate([0, 90, 0]) {
cylinder(r = R(NotchDiameter), h = 1, center = true);
translate([0, 0, NotchDiameter / 4]) sphere(r = R(NotchDiameter));
}
}
}
}
module boltSlot () {
cylinder(r = R(6), h = 46.5, center = true, $fn = 40);
cylinder(r = R(3.25), h = 55, center = true, $fn = 40);
}
module animationMotorBody () {
boltZOffset = -6;
difference () {
animationMotorBodyPositive();
//m3 bolts (vertical)
translate([31/2, 31/2, boltZOffset]) boltSlot();
translate([31/2, -31/2, boltZOffset]) boltSlot();
translate([-31/2, 31/2, boltZOffset]) boltSlot();
translate([-31/2, -31/2, -6]) boltSlot();
//cap m3s
rotate([0, 0, -60]) translate([14.5, 0, capM3OffsetZ]) {
rotate([0, 90, 0]) {
cylinder(r = R(3.25), h = 20, center = true, $fn = 40);
translate([0, 0, 6.5]) cylinder(r = R(6), h = 3, center = true, $fn = 40);
}
}
rotate([0, 0, 120]) translate([14.5, 0, capM3OffsetZ]) {
rotate([0, 90, 0]) {
cylinder(r = R(3.25), h = 20, center = true, $fn = 40);
translate([0, 0, 6.5]) cylinder(r = R(6), h = 3, center = true, $fn = 40);
}
}
}
}
module animationMotorCapPositive () {
difference() {
cylinder(r = R(BarrelDiameter), h = 10, center = true, $fn = 200);
translate([0, 0, -(10 /2) + (7.5/2) - 0.1]) cylinder(r = R(BearingDiameter), h = 7.5, center = true, $fn = 80);
cylinder(r = R(13), h = 10 + 1, center = true, $fn = 80);
}
translate([0, 0, -(10/2)-(5/2)]) difference() {
cylinder(r = R(BarrelDiameter) - 5.3, h = 5, center = true, $fn = 200);
cylinder(r = R(BarrelDiameter) - 7.5, h = 5 + 1, center = true, $fn = 200);
}
translate([0, 0, -(10/2)-(5/2)]) difference() {
union() {
rotate([0, 0, -60]) translate([13, 0, 0]) cube([6, 8, 5], center = true);
rotate([0, 0, 120]) translate([13, 0, 0]) cube([6, 8, 5], center = true);
}
cylinder(r = R(BearingDiameter)+1, h = 5 + 1, center = true, $fn = 200);
}
translate([0, 0, -(10/2)-(5/2)]) intersection() {
cylinder(r = R(BarrelDiameter), h = 5, center = true, $fn = 200);
translate([0, (BarrelDiameter / 2) - 2, 0]) cube([8-0.3, 8, 30], center = true);
}
}
module animationMotorCap () {
difference() {
animationMotorCapPositive();
rotate([0, 0, -60]) translate([14.5, 0, -(10/2)-(5/2)]) {
cube([2.5, 5.7, 6], center = true);
rotate([0, 90, 0]) cylinder(r = R(3.25), h = 10, center = true, $fn = 40);
}
rotate([0, 0, 120]) translate([14.5, 0, -(10/2)-(5/2)]) {
cube([2.5, 5.7, 6], center = true);
rotate([0, 90, 0]) cylinder(r = R(3.25), h = 10, center = true, $fn = 40);
}
//m3 set screw
rotate([0, 0, 180]) translate([14.5, 0, 0]) {
translate([2, 0, -6]) cube([2.5, 5.7, 20], center = true);
rotate([0, 90, 0]) {
cylinder(r = R(3.25), h = 20, center = true, $fn = 40);
translate([0, 0, 6.5]) cylinder(r = R(6), h = 3, center = true, $fn = 40);
}
}
}
}
module driveCoupling () {
D = 15.5;
H = 41-3;
Divot = 2.75;
difference() {
union() {
cylinder(r = R(D), h = H, center = true, $fn = 80);
translate([0, 0, 2]) cylinder(r = R(BearingInnerDiameter), h = H, center = true, $fn = 80);
}
translate([0, 0, -(H/2)+6.5]) rotate([0, 0, 90]) scale([1.05, 1.05, 1]) NEMA17_motor_shaft();
//bottom M3
translate([-4.5, 0, -(H/2) + 4.9]) cube([2.5, 5.7, 12], center = true);
translate([-10, 0, -(H/2) + 9 - 3]) rotate([90, 0, 90]) cylinder(r = R(3.25), h = 20, center = true, $fn = 40);
//top M3
translate([-4.5, 0, (H/2)-4.9+2]) cube([2.5, 5.7, 10], center = true);
translate([-10, 0, (H/2)-9+5]) rotate([90, 0, 90]) cylinder(r = R(3.25), h = 20, center = true, $fn = 40);
translate([0, 0, (H/2)-3]) difference() {
cylinder(r = R(7.8), h = 10.2, center = true, $fn = 100);
translate([-7.8+2, 0, 0]) cube([7.8, 7.8, 10+1], center = true);
}
}
}
/**
** DC Motor Design
**/
module animationMotorDCBodyPositive () {
rimH = 10 + 3.5;
difference () {
motorBarrel();
//hollow out
translate([0, 0, 4]) cylinder(r = R(BarrelDiameter) - 5, h = BarrelLength, center = true, $fn = 200);
//cut
translate([0, 0, 40]) cube([100, 100, BarrelLength], center = true);
cylinder(r = R(23), h = BarrelLength + 1, center = true, $fn = 100);
//window
translate([0, (BarrelDiameter / 2) - 2, -10+5+30]) cube([8, 8, 40], center = true);
}
//rim
translate([0, 0, -(BarrelLength / 2) - (rimH / 2)]) {
difference () {
cylinder(r = R(BarrelDiameter) + 2, h = rimH, center = true, $fn = 200);
cylinder(r = R(23), h = rimH + 1, center = true, $fn = 100);
}
}
//geared motor mount
translate([0, 0, -34 - 4 - 3 - 3.5]) {
intersection () {
rotate([0, 0, -90]) minimal_mount();
union () {
cylinder(r = R(BarrelDiameter) + 2, h = 10, center = true, $fn = 200);
translate([0, -30, 0]) cube([33, 60, 10], center = true);
}
}
}
//notch
$fn = 50;
rotate([0, 0, 35]) {
translate([BarrelDiameter / 2, 0, -(BarrelLength / 2) + NotchOffset]) {
rotate([0, 90, 0]) {
cylinder(r = R(NotchDiameter), h = 1, center = true);
translate([0, 0, NotchDiameter / 4]) sphere(r = R(NotchDiameter));
}
}
}
}
module boltSlotDC () {
cylinder(r = R(6), h = 52, center = true, $fn = 40);
}
module animationMotorDCBody () {
boltZOffset = -15.01;
padZ = 5.4;
difference () {
union () {
animationMotorDCBodyPositive();
translate([-22, -8.75-1.25, -34 + (4/2)-.5 - 5.04-1.5]) cube([16.1+1, 28.1+1, padZ], center = true);
}
cylinder(r = R(18), h = 160, center = true, $fn = 100);
translate ([0, -8, 0]) {
translate([MOTOR_MOUNT_Y/2, MOTOR_MOUNT_X/2, boltZOffset]) boltSlotDC();
translate([MOTOR_MOUNT_Y/2, -MOTOR_MOUNT_X/2, boltZOffset]) boltSlotDC();
translate([-MOTOR_MOUNT_Y/2, MOTOR_MOUNT_X/2, boltZOffset]) boltSlotDC();
translate([-MOTOR_MOUNT_Y/2, -MOTOR_MOUNT_X/2, boltZOffset]) boltSlotDC();
}
//microswitch
translate([-22, -8.75-1.25, -34 + (4/2)-.5 - 2]) {
cube([16 + 1.1, 28 + 1.1, 8], center = true);
translate([0, 0, 30]) cube([16, 28, 60], center = true);
translate([6, 7, 28]) cube([26, 15, 60], center = true);
//microswitch lever
translate([10, 8-3, 2-1]) cube([16, 15+6, 8], center = true);
}
//cap m3s
rotate([0, 0, -60]) translate([14.5, 0, capM3OffsetZ]) {
rotate([0, 90, 0]) {
cylinder(r = R(3.25), h = 20, center = true, $fn = 40);
translate([0, 0, 6.5]) cylinder(r = R(6), h = 3, center = true, $fn = 40);
}
}
rotate([0, 0, 120]) translate([14.5, 0, capM3OffsetZ]) {
rotate([0, 90, 0]) {
cylinder(r = R(3.25), h = 20, center = true, $fn = 40);
translate([0, 0, 6.5]) cylinder(r = R(6), h = 3, center = true, $fn = 40);
}
}
//microswitch m3s
translate([-22, -8.75-1.25, -34 + (4/2)-.5 - 5.04-1.5]) {
translate([-(16 / 2) + 3, (28 / 2) - 3, 0]) {
cylinder(r = R(3.5), h = padZ + 1, center = true, $fn = 40);
translate([0, 0, -5.9]) cylinder(r = R(6), h = padZ + 1, center = true, $fn = 40);
}
translate([(16 / 2) - 3, -(28 / 2) + 3, 0]) {
cylinder(r = R(3.5), h = padZ + 1, center = true, $fn = 40);
translate([0, 0, -5.9]) cylinder(r = R(6), h = padZ + 1, center = true, $fn = 40);
}
}
}
}
module animationMotorDCCapPositive () {
difference() {
cylinder(r = R(BarrelDiameter), h = 10, center = true, $fn = 200);
translate([0, 0, -(10 /2) + (7.5/2) - 0.1]) cylinder(r = R(BearingDiameter), h = 7.5, center = true, $fn = 80);
cylinder(r = R(13), h = 10 + 1, center = true, $fn = 80);
}
translate([0, 0, -(10/2)-(5/2)]) difference() {
cylinder(r = R(BarrelDiameter) - 5.3, h = 5, center = true, $fn = 200);
cylinder(r = R(BarrelDiameter) - 7.5, h = 5 + 1, center = true, $fn = 200);
}
translate([0, 0, -(10/2)-(5/2)]) difference() {
union() {
rotate([0, 0, -60]) translate([13, 0, 0]) cube([6, 8, 5], center = true);
rotate([0, 0, 120]) translate([13, 0, 0]) cube([6, 8, 5], center = true);
}
cylinder(r = R(BearingDiameter)+1, h = 5 + 1, center = true, $fn = 200);
}
translate([0, 0, -(10/2)-(5/2)]) intersection() {
cylinder(r = R(BarrelDiameter), h = 5, center = true, $fn = 200);
translate([0, (BarrelDiameter / 2) - 2, 0]) cube([8-0.3, 8, 30], center = true);
}
translate([0, 0, -(10/2)-(5/2)]) intersection() {
cylinder(r = R(BarrelDiameter), h = 5, center = true, $fn = 200);
translate([-22, -8.75-1.25, 0]) cube([16-0.3, 28-0.3, 20], center = true);
}
}
module animationMotorDCCap () {
difference() {
animationMotorDCCapPositive();
rotate([0, 0, -60]) translate([14.5, 0, -(10/2)-(5/2)]) {
cube([2.5, 5.7, 6], center = true);
rotate([0, 90, 0]) cylinder(r = R(3.25), h = 10, center = true, $fn = 40);
}
rotate([0, 0, 120]) translate([14.5, 0, -(10/2)-(5/2)]) {
cube([2.5, 5.7, 6], center = true);
rotate([0, 90, 0]) cylinder(r = R(3.25), h = 10, center = true, $fn = 40);
}
//m3 set screw
rotate([0, 0, 180]) translate([14.5, 0, 0]) {
translate([2, 0, -6]) cube([2.5, 5.7, 20], center = true);
rotate([0, 90, 0]) {
cylinder(r = R(3.25), h = 20, center = true, $fn = 40);
translate([0, 0, 6.5]) cylinder(r = R(6), h = 3, center = true, $fn = 40);
}
}
}
}
module driveCouplingDC () {
D = 15.5;
H = 49;
Divot = 2.75;
difference() {
union() {
cylinder(r = R(D), h = H, center = true, $fn = 80);
translate([0, 0, 2]) cylinder(r = R(BearingInnerDiameter), h = H, center = true, $fn = 80);
}
translate([0, 0, -(H/2)+5]) rotate([0, 0, 180]) scale([1.05, 1.05, 1]) motor_shaft();
//bottom M3
translate([-4.5, 0, -(H/2) + 4.9]) cube([2.5, 5.7, 12], center = true);
translate([-10, 0, -(H/2) + 9 - 3]) rotate([90, 0, 90]) cylinder(r = R(3.25), h = 20, center = true, $fn = 40);
//top M3
translate([-4.5, 0, (H/2)-4.9+2]) cube([2.5, 5.7, 10], center = true);
translate([-10, 0, (H/2)-9+5]) rotate([90, 0, 90]) cylinder(r = R(3.25), h = 20, center = true, $fn = 40);
translate([0, 0, (H/2)-3]) difference() {
cylinder(r = R(7.8), h = 10.2, center = true, $fn = 100);
translate([-7.8+2, 0, 0]) cube([7.8, 7.8, 10+1], center = true);
}
//divot for switch
translate([0, -D + Divot, 0]) cylinder(r = R(D), h = H, center = true, $fn = 80);
translate([0, -D + (3 * (Divot / 4)), 0]) cube([D, D, H + 1], center = true);
difference () {
translate([0, -D + 4, 0]) cube([D, D, H], center = true);
translate([0, -D + 4, 0]) cube([8, D+1, H + 1], center = true);
translate([4.25, -(D / 2) + 4.6, 0]) cylinder(r = R(D/3), h = H + 1, center = true, $fn = 60);
translate([-4.25, -(D / 2) + 4.6, 0]) cylinder(r = R(D/3), h = H + 1, center = true, $fn = 60);
}
}
}
module driveCouplingDCConnector () {
H = 17;
H2 = 20;
H3 = 4;
D1 = 9;
RIDGES=5;
SHAFT_D = 7.8;
translate([0, 0, 0]) difference() {
cylinder(r = R(SHAFT_D), h = H, center = true, $fn = 100);
translate([-SHAFT_D+2, 0, 0]) cube([SHAFT_D, SHAFT_D, H+1], center = true);
translate([-2, 0, -5]) rotate([90, 30, 90]) m3_nut();
}
translate([0, 0, (H/2)+(H2/2)]) cylinder(r = R(D1), h = H2, center = true, $fn = 80);
translate([0, 0, (H/2)+(H3/2)]) cylinder(r1 = R(BearingInnerDiameter), r2 = R(D1), h = H3, center = true, $fn = 80);
difference() {
union(){
for (i = [0 : RIDGES-1]) {
rotate([0, 0, i*(360/RIDGES)]) translate([0, 0, (H/2)+H2-3]) rotate([90, 0, 0]) cylinder(r = R(DriveDiameter1), h = 1, center = true, $fn = 80);
}
}
translate([0, 0, (H/2)+H2+(20/2)]) cube([20, 20, 20], center = true);
}
}
PART2 = "bellows_camera_board_adapter";
if (PART2 == "drive_coupling_DC_connector") {
driveCouplingDCConnector();
} else if (PART2 == "drive_coupling_DC") {
driveCouplingDC();
} else if (PART2 == "animation_motor_DC_cap") {
rotate([180, 0, 0]) animationMotorDCCap();
} else if (PART2 == "animation_motor_DC") {
animationMotorDCBody();
} else if (PART2 == "animation_motor") {
animationMotorBody();
} else if (PART2 == "animation_motor_cap") {
rotate([180, 0, 0]) animationMotorCap();
} else if (PART2 == "drive_coupling") {
driveCoupling();
} else if (PART2 == "bellows_camera_board_adapter") {
bodyCapBellowsAdapter();
} else if (PART2 == "bellows_camera_board") {
bellows_camera_board();
}

86
scad/arri_s_mount.scad Normal file
View File

@ -0,0 +1,86 @@
include <./common.scad>;
Z = 100 - 14.5;
baseX = 134.5;
baseY = 105.4;
baseZ = 20;
innerBaseX = 106.22;
innerBaseY = 75.88;
mountBoltsX = 71;
mountBoltsY = 90.66;
boltD = 5;
camBoltD = 10;
camBoltZ = 12;
module base () {
difference () {
cube([baseX, baseY, baseZ], center =true);
cube([innerBaseX, innerBaseY, baseZ + 1], center =true);
//bolts
bolts(boltD, baseZ + 1);
}
}
module bolts (boltD = 5, boltZ = 12) {
$fn = 60;
translate([mountBoltsX/2, mountBoltsY/2, 0]) cylinder(r = R(boltD), h = boltZ, center = true);
translate([-mountBoltsX/2, mountBoltsY/2, 0]) cylinder(r = R(boltD), h = boltZ, center = true);
translate([mountBoltsX/2, -mountBoltsY/2, 0]) cylinder(r = R(boltD), h = boltZ, center = true);
translate([-mountBoltsX/2, -mountBoltsY/2, 0]) cylinder(r = R(boltD), h = boltZ, center = true);
}
module camera_bolt (width = 20) {
$fn = 60;
translate([width/2, 0, 0]) cylinder(r = R(camBoltD), h = Z + 1);
translate([-width/2, 0, 0]) cylinder(r = R(camBoltD), h = Z + 1);
cube([width, camBoltD, Z + 1], center = true);
}
module wing_nuts (nutZ = 0) {
translate([mountBoltsX/2, mountBoltsY/2, nutZ]) rotate([0, 0, 5]) cube([3.5, 22, 11], center = true);
translate([-mountBoltsX/2, mountBoltsY/2, nutZ]) rotate([0, 0, 5]) cube([3.5, 22, 11], center = true);
translate([mountBoltsX/2, -mountBoltsY/2, nutZ]) rotate([0, 0, 5]) cube([3.5, 22, 11], center = true);
translate([-mountBoltsX/2, -mountBoltsY/2, nutZ]) rotate([0, 0, 5]) cube([3.5, 22, 11], center = true);
}
module mount () {
difference () {
rounded_cube([mountBoltsX + 20, baseY, Z], d = 20, center =true, $fn = 60);
//center void
translate([0, 0, -camBoltZ]) cube([mountBoltsX - 20, innerBaseY, Z], center =true);
//side void
translate([0, 0, -camBoltZ]) cube([baseX + 1, innerBaseY - 40, Z], center =true);
bolts(boltD + .4, Z + 1);
//inset
translate([0, 0, (Z / 2) - (Z / 2) + 15]) bolts(20, Z);
camera_bolt(35);
wing_nuts(-(Z / 2) + 20.5);
}
}
module center_fitting () {
SMALL_D = 4.5;
SMALL_Z = 9;
LARGE_D = 9.4;
translate([10.7, 0, 0]) cylinder(r = R(SMALL_D), h = SMALL_Z, center = true, $fn = 40);
difference () {
//cube
translate([(SMALL_D/2) + (LARGE_D / 2), 0, -(SMALL_Z/2)-(camBoltZ/2)]) cube([camBoltD + SMALL_D, camBoltD - 0.3, camBoltZ], center = true);
cylinder(r = R(LARGE_D), h = 60, center = true, $fn = 60);
translate([10.7 - 1, 0, 0]) difference () {
translate([(camBoltD + 1) / 2, 0, 0]) cube([camBoltD + 1, camBoltD + 1, 60], center = true);
cylinder(r = R(camBoltD), h = 60, center = true, $fn = 60);
}
}
}
//base();
//translate([0, 0, (baseZ/2) + (Z/2) + 5]) mount();
//translate([0, 0, (baseZ/2) + Z + 9])
//center_fitting();
mount();

View File

@ -20,19 +20,20 @@ module cmount_male(len = 4) {
module bellows_camera_board () {
H = 6;
INNER_D = 39;
difference () {
cube([60, 60, H], center = true);
//center
cylinder(r = 38 / 2, h = H + 1, center = true, $fn = 360);
cylinder(r = INNER_D / 2, h = H + 1, center = true, $fn = 360);
//center bevels
translate([0, 0, 2.25]) cylinder(r1 = 36 / 2, r2 = 40 / 2, h = 1.5, center = true, $fn = 360);
translate([0, 0, -2.25]) cylinder(r1 = 40 / 2, r2 = 36 / 2, h = 1.5, center = true, $fn = 360);
translate([0, 0, 2.25]) cylinder(r1 = (INNER_D - 2) / 2, r2 = (INNER_D + 2) / 2, h = 1.5, center = true, $fn = 360);
translate([0, 0, -2.25]) cylinder(r1 = (INNER_D + 2) / 2, r2 = (INNER_D - 2) / 2, h = 1.5, center = true, $fn = 360);
//corners
for (i = [0 : 3]) {
rotate([0, 0, i * (360 / 4) + 45 ]) translate([43.5, 0, 0]) cube([11, 11, H + 1], center = true);
}
//bolt
translate([0, 30, 0]) rotate([90, 0, 0]) cylinder(r = 1.6, h = 30, center = true, $fn = 30);
translate([0, 30, 0]) rotate([90, 0, 0]) cylinder(r = (4 / 2), h = 30, center = true, $fn = 30);
}
}
@ -53,5 +54,10 @@ module camera_mount () {
}
}
bellows_camera_board();
//translate([0, 0, 9]) color("red") camera_mount();
PART = "bellows_camera_board";
if (PART == "bellows_camera_board") {
bellows_camera_board();
} else if (PART == "camera_mount") {
camera_mount();
}

262
scad/capper.scad Normal file
View File

@ -0,0 +1,262 @@
include <common.scad>;
// Using a Tower Pro SG-5010 servo
// https://www.thingiverse.com/thing:83806 - Lego mount (has dimensions of servo body)
// https://www.thingiverse.com/thing:5241574 - Robot arm (just cool)
currentAngle=0;
LensVoidDiameter = 40; //mm
LensZ = 80;
LensY = 30;
CapOffsetX = -50;
CapOffsetY = -11;
CapLengthX = 50;
CapWidthZ = 4;
BoltSpacingX = 10;
BoltSpacingY = 49;
BoltD = 3.5;
RailSlotsX = 20;
RailSlotsD = 6;
MountBoltSpacingY=40;
OptoEndstopAdjustZ=2-9;
module OptoEndstop () {
$fn=30;
Y=5;
Z2=3.64-1.75;
difference () {
union() {
cube([11.15, 28.25, 1.75], center=true);
translate([0,14,0]) cylinder(r=R(6), h=1.75, center=true);
translate([0,-14,0]) cylinder(r=R(6), h=1.75, center=true);
}
translate([0,14,0]) cylinder(r=R(2.85), h=1.75+1, center=true);
translate([0,-14,0]) cylinder(r=R(2.85), h=1.75+1, center=true);
}
translate([-R(6.1)+1.2, R(28.25)-R(Y+4.15+4.15)-3.65, 0]) {
translate([0,R(Y)+R(4.15),-R(1.75)-R(10.15)]) cube([6.1, 4.15, 10.15], center=true);
translate([0,-R(Y)-R(4.15),-R(1.75)-R(10.15)]) cube([6.1, 4.15, 10.15], center=true);
}
translate([3,4, -R(1.75)-R(.75)]) cube([3.6, 15.7, .75], center=true);
}
module BoltVoid () {
cylinder(r=R(BoltD), h=20, center=true);
translate([0, 0, 4]) m3_nut(5);
}
module Mount () {
$fn = 200;
difference(){
union(){
//outer cylinder
translate([0, 0, 5]) difference(){
cylinder(r=R(LensVoidDiameter)+15, h=LensY, center=true);
cylinder(r=R(LensVoidDiameter)+5, h=LensY+1, center=true);
translate([0, 0, 10.01]) cylinder(r1=R(LensVoidDiameter), r2=R(LensVoidDiameter)+10, h=10, center=true);
}
translate([0,0,-(LensY/4)-(5/4)]) difference(){
cylinder(r=R(LensVoidDiameter)+5, h=R(LensY)-R(5)-10, center=true);
cylinder(r=R(LensVoidDiameter), h=LensY+1, center=true);
}
difference () {
union() {
translate([50, 0, -6]) cube([100, LensVoidDiameter + 30, 8], center=true);
translate([0, 0, -6]) cylinder(r=R(LensVoidDiameter)+12, h=8, center=true);
}
cylinder(r=R(LensVoidDiameter), h=LensY+1, center=true);
//servo
translate([50, 0, -6]) {
cube([20, 40.25, 10], center = true);
translate([BoltSpacingX/2, BoltSpacingY/2, 0]) BoltVoid();
translate([-BoltSpacingX/2, BoltSpacingY/2, 0]) BoltVoid();
translate([BoltSpacingX/2, -BoltSpacingY/2, 0]) BoltVoid();
translate([-BoltSpacingX/2, -BoltSpacingY/2, 0]) BoltVoid();
}
translate([50, 0, -6-3.01]) cube([2, 56, 2], center=true);
}
}
translate([0,R(LensVoidDiameter),1+4.5]) cube([LensVoidDiameter*2, LensVoidDiameter, 7], center=true);
//
translate([80, R(MountBoltSpacingY), 0]) RailSlots();
translate([80, -R(MountBoltSpacingY), 0]) RailSlots();
translate([0, 0, -4]) cylinder(r2=R(LensVoidDiameter)-5, r1=R(LensVoidDiameter)+5, h=LensY/2, center=true);
//endstop
/*translate([0, -34, 25-2-2-10]) {
difference () {
cube([14, 20, 50], center=true);
translate([0, R(LensVoidDiameter)+10+4.01, 0]) cylinder(r=R(LensVoidDiameter)+5, h=LensY + 29, center=true, $fn=200);
}
translate([0, 11, -14+9]) cylinder(r=R(22), h=4, center=true);
}*/
}
}
module Cap () {
$fn = 200;
difference(){
union(){
translate([CapOffsetX,CapOffsetY,0]){
cylinder(r=R(LensVoidDiameter) + 4, h=4, center = true);
translate([35,(LensVoidDiameter/4)+1,0]) {
difference () {
cube([CapLengthX,R(LensVoidDiameter),CapWidthZ], center=true);
translate([R(CapLengthX)-(R(LensVoidDiameter)/2), 0, 0]) difference() {
cube([R(LensVoidDiameter),R(LensVoidDiameter), CapWidthZ+1], center=true);
cylinder(r=R(LensVoidDiameter)/2, h=CapWidthZ+1+1, center=true);
translate([-R(LensVoidDiameter)/2, 0, 0]) cube([R(LensVoidDiameter),R(LensVoidDiameter), CapWidthZ+1], center=true);
}
}
}
}
translate([0, 0, -4]) cylinder(r=5,h=4,center=true);
}
translate([0, 0, -4]) cylinder(r1=R(5.85), r2=R(5.5), h=4.01,center=true, $fn=20);
cylinder(r=R(2.5), h=10,center=true);
translate([0, 0, 2.5]) cylinder(r=R(6.5), h=5,center=true);
}
//removed, unneeded
//translate([CapOffsetX,CapOffsetY - R(LensVoidDiameter) - 4, 1.25]) cylinder(r=R(15), h=1.5, center=true);
}
module MountFront () {
$fn=60;
difference () {
Mount();
translate([0, -50, 50-2]) cube([100, 100, 100], center=true);
translate([0, 0, 50-2+7]) cube([100, 100, 100], center=true);
translate([0,-30,-2]) cylinder(r=R(4), h=3, center=true);
rotate([0,0,40]) translate([0,-30,-2]) cylinder(r=R(4), h=3, center=true);
rotate([0,0,-40])translate([0,-30,-2]) cylinder(r=R(4), h=3, center=true);
rotate([0,0,80]) translate([0,-30,-2]) cylinder(r=R(4), h=3, center=true);
rotate([0,0,-80])translate([0,-30,-2]) cylinder(r=R(4), h=3, center=true);
translate([90, 0, -11]) rotate([45,0,0]) cube([70, 4.3, 4.3], center=true);
}
}
module MountBack () {
$fn=60;
difference () {
Mount();
translate([0, 0, -50-1.999]) cube([400, 100, 100], center=true);
translate([0, 50, -50+2+7]) cube([100, 100, 100], center=true);
}
//translate([0,-30,-2]) cylinder(r=R(3.9), h=3, center=true);
rotate([0,0,40]) translate([0,-30,-2]) cylinder(r=R(3.9), h=3, center=true);
rotate([0,0,-40])translate([0,-30,-2]) cylinder(r=R(3.9), h=3, center=true);
rotate([0,0,80]) translate([0,-30,-2]) cylinder(r=R(3.9), h=3, center=true);
rotate([0,0,-80])translate([0,-30,-2]) cylinder(r=R(3.9), h=3, center=true);
}
module RailSlots () {
translate([R(RailSlotsX), 0, 0]) cylinder(r=R(RailSlotsD), h=40, center=true);
translate([-R(RailSlotsX), 0, 0]) cylinder(r=R(RailSlotsD), h=40, center=true);
cube([RailSlotsX, RailSlotsD, 40], center=true);
}
module RailMount () {
//
X=110;
RailD=15;
RailSpacingY=80;
$fn=60;
difference () {
translate([X, 0, -14]) difference () {
cube([100, LensVoidDiameter + 30.6, 8], center=true);
//
translate([-40, R(MountBoltSpacingY), 0]) cylinder(r=R(6),h=40,center=true);
translate([-40, -R(MountBoltSpacingY), 0]) cylinder(r=R(6),h=40,center=true);
}
}
translate([X, 0, -11]) rotate([45,0,0]) cube([100, 4, 4], center=true);
translate([X + R(100), 0, -14]) cube([8, LensVoidDiameter + 30.6, 28], center=true);
translate([X + R(100) + 5 ,R(RailSpacingY),-14]) difference() {
translate([-2.5, -2.5, 0]) cylinder(r=R(RailD + 5), h=28, center=true);
cylinder(r=R(RailD), h=28+1, center=true);
}
}
module OptoEndstopMount () {
translate([-5,9.5,20]) {
difference() {
translate([0, 0, 1-7.25]) cube([14-0.3-0.3, 14, 32+4], center=true);
//lens void
translate([0, R(LensVoidDiameter)+5+4, 0]) cylinder(r=R(LensVoidDiameter)+5, h=LensY + 29, center=true, $fn=200);
//connector void
translate([0,-8.3, -14.5]) cube([9, 8, 5], center=true);
//bolts
translate([2,-5,-13.25+OptoEndstopAdjustZ]) rotate([90, 0, 0]) cylinder(r=R(2.9),h=20,center=true, $fn=40);
translate([2,-5,15+OptoEndstopAdjustZ]) rotate([90, 0, 0]) cylinder(r=R(2.9),h=20,center=true, $fn=40);
//main void
translate([-0.5,1,-3]) cube([8,20,15],center=true);
//pathway void
translate([0,6,-2]) cylinder(r=R(22), h=6, center=true);
//smd voids
translate([5, -6.5, -3]) cube([3.6, 1, 18], center=true);
}
}
}
module Debug () {
Mount();
translate([-CapOffsetX,-CapOffsetY,5.71]) rotate([0,0,currentAngle]) Cap();
//color("green") RailMount();
//translate([5, -38, -11.8+OptoEndstopAdjustZ]) rotate([0, -90, 0]) opto_endstop();
//color("green") translate([5, -38, -11.8]) OptoEndstopMount();
//translate([1.5, -38 + 2 -10, -11.8 + 11 + 2 +.75]) rotate([90, 0, 0])OptoEndstop();
translate([130, 0, 0]) Base();
translate([80, 0, 30]) cube([110 + 50, 10, 10], center = true);
}
module Base () {
$fn = 60;
difference () {
cube([110, LensVoidDiameter + 30, 8], center=true);
translate([-45, R(MountBoltSpacingY), 0]) cylinder(r=R(RailSlotsD) + .25, h=40, center=true);
translate([-45, -R(MountBoltSpacingY), 0]) cylinder(r=R(RailSlotsD) + .25, h=40, center=true);
}
translate([15, 0, -R(50)]) cube([10, LensVoidDiameter + 30, 50], center=true);
difference () {
translate([50, 0, -R(50)]) cube([10, LensVoidDiameter + 30, 50], center=true);
translate([50, 20, -40]) rotate([0, 90, 0]) {
cylinder(r=R(RailSlotsD) + .25, h=40, center=true);
translate([0, 0, -11]) rotate([0, 0, 30]) hex(13.5, 22);
}
translate([50, -20, -40]) rotate([0, 90, 0]) {
cylinder(r=R(RailSlotsD) + .25, h=40, center=true);
translate([0, 0, -11]) rotate([0, 0, 30]) hex(13.5, 22);
}
}
}
Render="Base";
if (Render=="Debug") {
Debug();
} else if (Render=="Cap") {
Cap();
} else if (Render=="MountFront") {
MountFront();
} else if (Render=="MountBack") {
rotate([180, 0, 0]) MountBack();
} else if (Render=="RailMount") {
RailMount();
} else if (Render=="OptoEndstopMount") {
echo("Deprecated");
//rotate([-90,0,0]) OptoEndstopMount();
} else if (Render=="Base") {
Base();
}

View File

@ -30,3 +30,109 @@ module trap_cube(height = 19, top_x = 30, top_y = 34, bottom_x = 45, bottom_y =
}
}
}
echo("common.scad - R()");
function R (diameter) = diameter / 2.0;
module hex (diag = 10, h = 1) {
cylinder(r = diag / 2, h = h, center = true, $fn = 6);
}
echo("common.scad - m3_nut");
module m3_nut (H = 5) {
cylinder(r=R(6.6), h=H, center=true, $fn=6);
}
echo("common.scad - m4_nut");
module m4_nut (H = 5, DIAG = 8.1) {
//tolerance
hex(diag = DIAG, h = H);
}
echo("common.scad - m5_nut");
module m5_nut (H = 5, DIAG = 9.1) {
hex(diag = DIAG, h = H);
}
module opto_endstop(){
difference(){
union(){
// base PCB
color("green") cube([33.0,1.6,10.5]);
// add the switch module
translate([8.4,1.6,10.5/2-6.4/2]) optoswitch();
// connector
translate([0.2,-7,0]) color("white") cube([5.8,7,10.5]);
// led
translate([3.5,1.6,10.5/2-1.5/2]) color("red") cube([2,0.7,1.5]);
}
translate([8.4,0,10.5/2-6.4/2]) {
for ( hole = [2.75,24.5-2.75] ){
rotate([90,0,0]) translate([hole,6.4/2,-4]) cylinder(r=1.5, h=4.5,$fn=40);
}
}
}
}
// switch module
module optoswitch() {
difference(){
union (){
color("gray") cube([24.5,3.5,6.4]);
color("gray")translate([6.63,0,0]) cube([4.45,11.3,6.3]);
color("gray")translate([13.63,0,0]) cube([4.45,11.3,6.3]);
}
for ( hole = [2.75,24.5-2.75] ){
rotate([90,0,0]) translate([hole,6.4/2,-4]) cylinder(r=1.5, h=4.5,$fn=40);
}
}
}
module NEMA17_motor_shaft (L = 22.75) {
//shaft
difference () {
cylinder(r = R(5), h = L, center = true, $fn = 30);
translate([0, 4.5, 4.7]) cube([5, 5, L+1], center = true);
}
}
//NEMA17 Stepper
module NEMA17 ( H = 33 ) { //alt = 47.5
difference () {
cube([42, 42, H], center = true);
for (i = [0 : 3]) {
rotate([0, 0, (i * 90) + 45]) translate([29.7, 0, 0]) cube([5.5, 5.5, H + 1], center = true);
}
translate([31/2, 31/2, (H/2)-1.9]) cylinder(r = R(3), h = 4, center = true, $fn=30);
translate([-31/2, 31/2, (H/2)-1.9]) cylinder(r = R(3), h = 4, center = true, $fn=30);
translate([31/2, -31/2, (H/2)-1.9]) cylinder(r = R(3), h = 4, center = true, $fn=30);
translate([-31/2, -31/2, (H/2)-1.9]) cylinder(r = R(3), h = 4, center = true, $fn=30);
}
//pad
translate([0, 0, (H/2) + (1.9/2)]) {
cylinder(r = R(22), h = 1.9, center = true, $fn = 100);
}
translate([0, 0, (H/2) + (L/2)]) NEMA17_motor_shaft();
}
//Geartisan Worm Gear Motor - JSX40-370
module geared_motor () {
cube([46, 32, 21], center = true);
translate([(46 / 2) + (30 / 2), 0, 1.5]) rotate([0, 90, 0]) cylinder(r = 24 / 2, h = 30, center = true, $fn = 80);
translate([-(46 / 2) + 14.5, 0, -18.5]) rotate([0, 0, 90]) motor_shaft();
//pad
translate([-(46 / 2) + 14.5, 0, -(1 / 2) - 10.5]) cylinder(r = 13 / 2, h = 1, center = true, $fn = 60);
//mount pads
translate([-0.5, 0, -(1.5 / 2) - 10.5]) motor_mounts();
}
module microswitch (position = [0, 0, 0], rotation = [0, 0, 0]) {
translate(position) {
rotate(rotation) {
cube([16, 28, 9.5], center = true);
translate([10, 8, 0]) rotate([0, 0, -7]) cube([1, 28, 4], center = true);
translate([8 + 7, 14 + 8, 0]) cylinder(r = 2.5, h = 4, center = true);
translate([0, -19, 0]) cube([6, 11, 9.5], center = true);
}
}
}

View File

@ -0,0 +1,33 @@
SQUARE_INNER = 7.8;
time = 0;
module reel_holder (top = true, base = true) {
$fn = 60;
difference(){
translate([0, 0, -1.5]) cube([SQUARE_INNER, SQUARE_INNER, 21.5], center= true);
for (i = [0:4]) {
rotate([0, 0, (i * 90)]){
translate([(SQUARE_INNER / 2) + .4, (SQUARE_INNER / 2) + .4, 18.5 / 2]) rotate([0, -15, 45]) cube([2.5, SQUARE_INNER, SQUARE_INNER], center = true);
}
}
}
difference () {
union() {
translate([0, 0, (18.5 / 2) + (3.5 / 2)]) cylinder(r = SQUARE_INNER / 2, h = 3.5, center = true);
translate([0, 0, (18.5 / 2) + (7.5 / 2)]) sphere(SQUARE_INNER / 2);
}
translate ([0, 0, (18.5 / 2) + 7.5]) cube([10, 10, 2], center = true);
}
if (base) {
difference () {
translate([0, 0, -(18.5/ 2) - (3 / 2) - 3]) cylinder(r = 16 /2, h = 3, center = true);
//translate([0, 0, -14.3]) cube([4, 4, 2], center = true); //notch
difference() {
translate([0, 0, -14.3]) cylinder(r = 8 / 2, h = 2, center = true);
translate([0, 6, -14.3]) cube([8, 8, 2], center = true);
}
}
}
}
//rotate([0, 0, time]) reel_holder();

385
scad/jk_lens_assembly.scad Normal file
View File

@ -0,0 +1,385 @@
//
// JK lens assembly
//
include <./common.scad>;
include <./bellows.scad>;
include <./knurledFinishLib_v2.scad>;
PART = "";
LinearBearingOuterDiameter = 15;
LinearBearingHeight = 24;
LinearBearingBoreDiameter = 8;
ThreadDiameter = 8;
LinearMotionDiameter = 8;
TNutDiameter1 = 22;
TNutDiameter2 = 10.2;
TNutInnerDiameter = 8;
TNutHeight1 = 3.5;
TNutHeight2 = 15;
TNutOffset = 1.5;
RodLength = 150;
ZOffset = 120;
XOffset = 38;
XWidth = 50;
FrontOffset = 0;
BackOffset = 15;
LinearMotionX = 22;
LinearMotionY = 20;
LinearMotionZ = 14;
XPosition = 0;
ZPosition = 0;
module linearBearing (padD = 0, padH = 0) {
difference () {
cylinder(r = R(LinearBearingOuterDiameter + padD), h = LinearBearingHeight + padH, center = true, $fn = 100);
cylinder(r = R(LinearBearingBoreDiameter), h = LinearBearingHeight + padH + 1, center = true, $fn = 60);
}
}
module threadedRod (H = 40, pad = 0) {
color("green") cylinder(r = R(ThreadDiameter + pad), h = H, center = true, $fn = 60);
}
module linearMotionRod (H = 40, pad = 0) {
color("blue") cylinder(r = R(LinearMotionDiameter + pad), h = H, center = true, $fn = 60);
}
module TNut (padD = 0, padH = 0) {
color("red") difference () {
union () {
translate([0, 0, -(TNutHeight2 / 2) + (TNutHeight1 / 2) + TNutOffset]) cylinder(r = R(TNutDiameter1 + padD), h = TNutHeight1, center = true, $fn = 100);
cylinder(r = R(TNutDiameter2), h = TNutHeight2 + padH, center = true, $fn = 80);
}
cylinder(r = R(TNutInnerDiameter), h = TNutHeight2 + 1, center = true, $fn = 60);
}
}
module m3Bolt (bolt = 20) {
cylinder(r = 3.1 / 2, h = bolt, center = true, $fn = 40);
}
module m4Bolt (bolt = 10) {
cylinder(r = R(4.25), h = bolt, center = true, $fn = 40);
}
module m3BoltNut (bolt = 20, nut = 3.5) {
m3Bolt(bolt);
translate([0, 0, nut]) color("red") {
cylinder(r = 8 / 2, h = 2.5, center = true, $fn = 6);
translate([-4, 0, 0]) cube([8, 6.9, 2.5], center = true);
}
}
module m4BoltNut (bolt = 10, nut = 3.5) {
m4Bolt(bolt);
translate([0, 0, nut]) color("red") {
m4_nut();
translate([-10, 0, 0]) cube([20, 6.9, 3.5], center = true);
}
}
module lensAssemblyBellowsBoard () {
//bottom
difference () {
union () {
rotate([0, 0, 90]) bellows_camera_board();
translate([0, -XOffset, FrontOffset]) rotate([0, 90, 0]) cylinder(r = R(22), h = XWidth, center = true, $fn = 80);
}
rotate([-90, 0, 0]) {
translate([-(XWidth/2) + 2.5, -FrontOffset, -XOffset]) rotate([0, 90, 0]) TNut(0.3, 0.3);
//m3s
// -centered
translate([-(XWidth/2) + 2.5 + 5, -FrontOffset - 8, -XOffset]) rotate([0, -90, 0]) rotate([0, 0, 90]) m3BoltNut();
// -top no nut
translate([-(XWidth/2) + 2.5 + 5, -FrontOffset, -XOffset + 8]) rotate([0, -90, 0]) m3Bolt();
// -bottom no nut
translate([-(XWidth/2) + 2.5 + 5, -FrontOffset, -XOffset - 8]) rotate([0, -90, 0]) m3Bolt();
translate([(XWidth/2) - 2.5, -FrontOffset, -XOffset]) rotate([0, -90, 0]) TNut(0.3, 0.3);
//m3s
// -center
translate([(XWidth/2) - 2.5 - 5, -FrontOffset - 8, -XOffset]) rotate([0, 90, 0]) rotate([0, 0, 90]) m3BoltNut();
// -top no nut
translate([(XWidth/2) - 2.5 - 5, -FrontOffset, -XOffset + 8]) rotate([0, 90, 0]) m3Bolt();
// -bottom no nut
translate([(XWidth/2) - 2.5 - 5, -FrontOffset, -XOffset - 8]) rotate([0, 90, 0]) m3Bolt();
}
rotate([-90, 0, 0]) translate([0, -FrontOffset, -XOffset]) rotate([0, 90, 0]) threadedRod(RodLength, 0.5);
translate([0, -XOffset, -10.5]) cube([100,30, 15], center = true);
}
//top
difference () {
translate([0, XOffset, FrontOffset]) rotate([0, 90, 0]) cylinder(r = R(25), h = 24, center = true, $fn = 80);
rotate([-90, 0, 0]) {
translate([0, -FrontOffset, XOffset]) rotate([0, 90, 0]) linearBearing(0.25);
}
translate([0, XOffset, -10.5]) cube([24 + 1,30, 15], center = true);
rotate([-90, 0, 0]) translate([0, -FrontOffset, XOffset]) rotate([0, 90, 0]) linearMotionRod(RodLength);
}
}
module topLinearAttachmentBlock () {
cube([LinearMotionX, LinearMotionY + 2, LinearMotionZ], center = true);
}
module lensAssemblyThreadedZ () {
Z = 90;
difference () {
union () {
//main cylinder
rounded_cube([22, 22, Z], d = 8, $fn = 30, center = true);
//top linear motion rod attachment block
translate([0, -BackOffset, (Z/2) - (LinearMotionZ/2)]) topLinearAttachmentBlock();
//bottom threaded rod block
translate([0, -BackOffset, -XOffset]) rotate([0, 90, 0]) cylinder(r = R(22), h = 22, center = true, $fn = 80);
}
//------
//threaded rod void
threadedRod(Z + 20, 0.5);
//board nut void
translate([0, -10, 0]) rotate([0, 90, 0]) cylinder(r = R(12), h = 30, center = true, $fn = 40);
//T nuts
//top
translate([0, 0, (Z / 2) - 4]) rotate([180, 0, 0]) TNut(0.3, 0.3);
//bottom
translate([0, 0, -(Z / 2) + 4]) TNut(0.3, 0.3);
//----
//T nut M3 bolts
//top
translate([0, 0, (Z / 2) - 4]) {
translate([-8, 0, 0]) rotate([180, 0, 0]) m3BoltNut();
translate([8, 0, 0]) rotate([0, 0, 180]) rotate([180, 0, 0]) m3BoltNut();
translate([0, 8, 0]) rotate([0, 0, -90]) rotate([180, 0, 0]) m3BoltNut();
}
//bottom
translate([0, 0, -(Z / 2) + 4]) {
translate([-8, 0, 0]) m3BoltNut();
translate([8, 0, 0]) rotate([0, 0, 180]) m3BoltNut();
translate([0, 8, 0]) rotate([0, 0, -90]) m3BoltNut();
}
//------
//top linear motion rod voids
//top gap to close
translate([0, -(LinearMotionY/2) - 9, (Z/2) - (LinearMotionZ/2)]) cube([LinearMotionX + 1, LinearMotionY, 2], center = true);
//rod
translate([0, -BackOffset, (Z/2) - (LinearMotionZ/2)]) rotate([0, 90, 0]) cylinder(r = R(LinearMotionDiameter)+.2, h = LinearMotionX + 1, center = true, $fn = 60);
//m4 bolt top
translate([0, -BackOffset - 8 + 2, (Z/2) - (LinearMotionZ/2)]) m4Bolt(LinearMotionZ + 1);
//m4 nut top
translate([0, -BackOffset - 8 + 2, (Z/2) - (LinearMotionZ/2) - 6]) m4_nut();
//------
//bottom threaded rod void
translate([0, -BackOffset, -XOffset]) rotate([0, 90, 0]) threadedRod(22 + 1, 0.5);
//flatten bottom
translate([0, -BackOffset, -(Z / 2) - 11]) cube([23, 22, 22], center = true);
}
}
module lensAssemblyLinearZ () {
Z = 90;
difference () {
union () {
//main cylinder
rounded_cube([22, 22, Z], d = 8, $fn = 30, center = true);
//top
translate([0, -BackOffset, (Z / 2) - (LinearMotionZ/2)]) topLinearAttachmentBlock();
//bottom
translate([0, -BackOffset, -XOffset]) rotate([0, 90, 0]) cylinder(r = R(22), h = 22, center = true, $fn = 80);
}
//x linear motion rod void
translate([9, -BackOffset, (Z / 2) - (LinearMotionZ/2)]) rotate([0, 90, 0]) linearMotionRod(50, 0.3);
//z linear motion rod
linearMotionRod(250, 0.6);
//top gap to close
translate([0, -(LinearMotionY/2) - 9, (Z/2) - (LinearMotionZ/2)]) cube([LinearMotionX + 1, LinearMotionY, 2], center = true);
//m4 bolt top
translate([0, -BackOffset - 8 + 2, (Z/2) - (LinearMotionZ/2)]) m4Bolt(LinearMotionZ + 1);
//m4 nut top
translate([0, -BackOffset - 8 + 2, (Z/2) - (LinearMotionZ/2) - 6]) m4_nut();
//flatten bottom
translate([0, -BackOffset, -(Z / 2) - 11]) cube([23, 22, 22], center = true);
//z linear bearing
translate([0, 0, -(Z / 2) + (LinearBearingHeight / 2) - 2 ]) {
linearBearing(0.25, 0.3);
}
//z linear bearing
translate([0, 0, (Z / 2) - (LinearBearingHeight / 2) + 2]) {
linearBearing(0.25, 0.3);
}
//x threaded rod
translate([0, -BackOffset, -XOffset]) rotate([0, 90, 0]) threadedRod(50, 0.5);
}
}
module m5_nut_bolt () {
cylinder(r = R(4.95), h = 30, center = true, $fn = 30);
translate([0, 0, 20/2]) rotate([0, 0, 30]) m5_nut();
}
module lensAssemblyBaseZ () {
H = 22 + 12 + 12;
TOP_X = 74;
BOTTOM_X = 88;
Z_OFFSET = (12/2)+(22/2);
RAILS = 160;
RAIL_D = 30; //with clearance
BOTTOM_CORNER_ADJUST_X = 4;
translate([0, 0, Z_OFFSET]) difference () {
translate([0, 6, -(24 / 2)]) cube([150, 45 + 12, H], center = true);
translate([ZOffset/2, 0, 5]) linearMotionRod(22 + 1, 0.2);
translate([-ZOffset/2, 0, 0]) threadedRod(50, 0.5);
translate([ZOffset/2+10, 0, 3]) rotate([0, 90, 0]) m4BoltNut(20, -1);
//shelf void
translate([0, 12, -17]) cube([160 + 1, 45 + 0.1, 12], center = true);
//top corner voids
translate([(150 / 2) + (TOP_X / 2), 6 + (45 + 12) - 20, -(24 / 2) + 12]) cube([150, 45 + 12, H], center = true);
translate([-(150 / 2) - (TOP_X / 2), 6 + (45 + 12) - 20, -(24 / 2) + 12]) cube([150, 45 + 12, H], center = true);
//bottom corner voids
translate([(150 / 2) + (BOTTOM_X / 2), 6, -(24 / 2) - 22 - 12]) cube([150, 45 + 12 + 1, H], center = true);
translate([-(150 / 2) - (BOTTOM_X / 2), 6, -(24 / 2) - 22 - 12]) cube([150, 45 + 12 + 1, H], center = true);
//additional corner off right side
translate([-(150 / 2) - (BOTTOM_X / 2) + BOTTOM_CORNER_ADJUST_X, 6, -(24 / 2) - 22 - 12]) cube([150, 45 + 12 + 1, H], center = true);
//bottom bolts
translate([25, 25, -18 - Z_OFFSET]) m5_nut_bolt();
translate([-25, 25, -18 - Z_OFFSET]) m5_nut_bolt();
translate([25, -5, -18 - Z_OFFSET]) m5_nut_bolt();
translate([-25, -5, -18 - Z_OFFSET]) m5_nut_bolt();
//top bolts
translate([25, 25, 17.5 - Z_OFFSET]) {
rotate([180, 0, 0]) m5_nut_bolt();
translate([0, 0, 10]) rotate([0, 0, 30]) cylinder(r = R(20), h = 20, center = true, $fn = 6);
}
translate([-25, 25, 17.5 - Z_OFFSET]) {
rotate([180, 0, 0]) m5_nut_bolt();
translate([0, 0, 10]) rotate([0, 0, 30]) cylinder(r = R(20), h = 20, center = true, $fn = 6);
}
translate([25, -5, 17.5 - Z_OFFSET]) {
rotate([180, 0, 0]) m5_nut_bolt();
translate([0, 0, 10]) rotate([0, 0, 30]) cylinder(r = R(20), h = 20, center = true, $fn = 6);
}
translate([-25, -5, 17.5 - Z_OFFSET]) {
rotate([180, 0, 0]) m5_nut_bolt();
translate([0, 0, 10]) rotate([0, 0, 30]) cylinder(r = R(20), h = 20, center = true, $fn = 6);
}
//rails void
translate([RAILS / 2, 0, -Z_OFFSET -6.5-5.75]) rotate([90, 0, 0]) cylinder(r = R(RAIL_D), h = 100, center = true, $fn = 80);
translate([-RAILS / 2, 0, -Z_OFFSET -6.5-5.75]) rotate([90, 0, 0]) cylinder(r = R(RAIL_D), h = 100, center = true, $fn = 80);
}
//debug
//translate([0, 12, 0]) color("green") cube([160, 45, 12], center = true);
//translate([RAILS / 2, 0, -6.5-5.75]) rotate([90, 0, 0]) cylinder(r = R(RAIL_D), h = 100, center = true, $fn = 80);
//translate([-RAILS / 2, 0, -6.5-5.75]) rotate([90, 0, 0]) cylinder(r = R(RAIL_D), h = 100, center = true, $fn = 80);
}
module lensAssemblyTopZ () {
difference () {
rounded_cube([150, 22, 15], d = 8, $fn = 30, center = true);
translate([ZOffset/2, 0, 0]) linearMotionRod(22 + 1, 0.2);
translate([-ZOffset/2, 0, 0]) threadedRod(50, 0.5);
translate([ZOffset/2+10, 0, 0]) rotate([0, 90, 0]) m4BoltNut(20, -1);
}
}
module lensAssemblyThreadedCollar (H = 8, pad = 0) {
difference () {
union () {
cylinder(r = R(26), h = H, center = true, $fn = 80);
}
threadedRod(H*2, 0.1 + pad);
translate([8.5, 0, 0]) rotate([0, 90, 0]) m3BoltNut(10, -1);
}
}
module lensAssemblyThreadedKnob () {
H = 8;
D1 = 38.7;
difference () {
union () {
translate([0, 0, -H/2]) knurled_cyl(H, D1, 2, 2, .3, 0, 0);
translate([0, 0, H]) lensAssemblyThreadedCollar(H);
}
translate([0, 0, H]) threadedRod(H*2, 0.1);
}
}
module debug () {
translate([0, 0, ZPosition]) {
translate([-ZOffset/2, BackOffset, 0]) lensAssemblyThreadedZ();
translate([ZOffset/2, BackOffset, 0]) lensAssemblyLinearZ();
translate([ZOffset/2, BackOffset, (90 / 2) - (LinearBearingHeight / 2) + 2]) color("green") linearBearing();
translate([ZOffset/2, BackOffset, -(90 / 2) + (LinearBearingHeight / 2) - 2]) color("green") linearBearing();
translate([-ZOffset/2, BackOffset, 40]) rotate([180, 0, 0]) TNut();
translate([-ZOffset/2, BackOffset, -40]) TNut();
//X axis
translate([0, -FrontOffset, -XOffset]) rotate([0, 90, 0]) threadedRod(RodLength);
//translate([-(ZOffset/2) - 24, -FrontOffset, -XOffset]) rotate([0, 90, 0]) lensAssemblyThreadedKnob();
translate([-(ZOffset/2) + 16, -FrontOffset, -XOffset]) rotate([0, 90, 0]) lensAssemblyThreadedCollar();
translate([0, -FrontOffset, XOffset]) rotate([0, 90, 0]) linearMotionRod(RodLength);
translate([XPosition, 0, 0]) {
rotate([90, 0, 0]) lensAssemblyBellowsBoard();
translate([0, 0, 40]) rotate([0, 90, 0]) color("green") linearBearing();
translate([-22.5, 0, -XOffset]) rotate([0, 90, 0]) TNut();
translate([22.5, 0, -XOffset]) rotate([0, -90, 0]) TNut();
}
}
//Z axis
translate([-ZOffset/2, BackOffset, 0]) threadedRod(RodLength + 20);
//translate([-ZOffset/2, BackOffset, -((RodLength + 20)/2)-8]) lensAssemblyThreadedKnob();
translate([-ZOffset/2, BackOffset, -((RodLength + 20)/2)+31]) lensAssemblyThreadedCollar();
translate([ZOffset/2, BackOffset, 0]) linearMotionRod(RodLength);
translate([0, BackOffset, -70]) lensAssemblyBaseZ();
translate([0, 130, 0]) rotate([90, 0, 0]) bellows_camera_board();
translate([0, 130/2, 0]) color("blue") {
difference () {
cube([70, 130-10, 70], center = true);
cube([40, 130 + 1, 40], center = true);
}
}
}
PART = "lens_assembly_base_z";
if (PART == "lens_assembly_camera_bellows_board") {
bellows_camera_board();
} else if (PART == "lens_assembly_bellows_board") {
lensAssemblyBellowsBoard();
} else if (PART == "lens_assembly_threaded_z") {
lensAssemblyThreadedZ();
} else if (PART == "lens_assembly_linear_z") {
lensAssemblyLinearZ();
} else if (PART == "lens_assembly_base_z") {
lensAssemblyBaseZ();
} else if (PART == "lens_assembly_top_z") {
lensAssemblyTopZ();
} else if (PART == "lens_assembly_threaded_knob") {
lensAssemblyThreadedKnob();
} else if (PART == "lens_assembly_threaded_collar") {
lensAssemblyThreadedCollar(6, 0.2);
} else {
debug();
}

45
scad/jk_rails.scad Normal file
View File

@ -0,0 +1,45 @@
include <./common.scad>;
RAIL_SPACING = 100;
RAIL_H = 70;
RAIL_LEN = 400;
RAIL_D=25.4;
module rail (H = 100) {
cylinder(r = R(RAIL_D), h = H, center = true, $fn = 60);
}
module rails () {
translate([RAIL_SPACING/2, 0, RAIL_H]) rotate([90, 0, 0]) rail(RAIL_LEN);
translate([-RAIL_SPACING/2, 0, RAIL_H]) rotate([90, 0, 0]) rail(RAIL_LEN);
}
module end () {
L = 50;
T = 20;
translate ([0, -L / 2, 0]) {
difference () {
union () {
translate([RAIL_SPACING/2, 0, RAIL_H]) rotate([90, 0, 0]) {
cylinder(r = R(35), h = L, center = true, $fn = 60);
}
translate([-RAIL_SPACING/2, 0, RAIL_H]) rotate([90, 0, 0]) {
cylinder(r = R(35), h = L, center = true, $fn = 60);
}
translate([0, 0, RAIL_H + (35 / 2) - (T / 2)]) cube([RAIL_SPACING, L, T], center = true);
translate([RAIL_SPACING/2 - (5 / 2), 5, RAIL_H / 2]) cube([40, 40, RAIL_H], center = true);
translate([-RAIL_SPACING/2 + (5 / 2), 5, RAIL_H / 2]) cube([40, 40, RAIL_H], center = true);
}
translate([RAIL_SPACING/2, 0, RAIL_H]) rotate([90, 0, 0]) {
rail(L + 1);
}
translate([-RAIL_SPACING/2, 0, RAIL_H]) rotate([90, 0, 0]) {
rail(L + 1);
}
}
}
}
color("blue") rails();
translate([0, RAIL_LEN / 2, 0]) end();

BIN
scad/mono_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

View File

@ -522,3 +522,8 @@ module bolex_stand () {
}
}
PART="rod";
if (PART == "rod") {
rod();
}

214
scad/takeup.scad Executable file
View File

@ -0,0 +1,214 @@
include <common.scad>;
include <daylight_spool_mount.scad>;
COUPLING_D = 37;
WASHER_D = 35.7; //1 + 1/3 diameter?
WASHER_H = 2.4;
MOTOR_SHAFT_D = 6;
MOTOR_SHAFT_H = 16;
MOTOR_SHAFT_HOBBLE = 1;
MOTOR_MOUNT_X = 32.5;
MOTOR_MOUNT_Y = 17.5;
module hex (diag = 10, h = 1) {
cylinder(r = diag / 2, h = h, center = true, $fn = 6);
}
module motor_shaft () {
difference () {
cylinder(r = R(MOTOR_SHAFT_D), h = MOTOR_SHAFT_H, center = true, $fn = 60);
translate([MOTOR_SHAFT_D - MOTOR_SHAFT_HOBBLE, 0, 0]) cube([MOTOR_SHAFT_D, MOTOR_SHAFT_D, MOTOR_SHAFT_H + 1], center = true);
}
}
module motor_mounts () {
Z = 1.5;
D = 7.5 + 0.3;
translate([MOTOR_MOUNT_X / 2, MOTOR_MOUNT_Y / 2, 0]) motor_mount_pad(D, Z);
translate([-MOTOR_MOUNT_X / 2, MOTOR_MOUNT_Y / 2, 0]) motor_mount_pad(D, Z);
translate([MOTOR_MOUNT_X / 2, -MOTOR_MOUNT_Y / 2, 0]) motor_mount_pad(D, Z);
translate([-MOTOR_MOUNT_X / 2, -MOTOR_MOUNT_Y / 2, 0]) motor_mount_pad(D, Z);
}
module motor_mount_pad (D, Z) {
difference () {
cylinder(r = R(D), h = Z, center = true, $fn = 40);
//bolt void
cylinder(r = R(2.5), h = Z + 1, center = true, $fn = 40);
}
}
module magnetic_coupling (MAGNETS = 4, MAGNET_D = 8.1, MAGNET_H = 2.5) {
H = 3;
OFFSET = 12;
difference () {
union () {
cylinder(r = R(COUPLING_D), h = MAGNET_H + H, center = true, $fn = 100);
translate([0, 0, -6]) cylinder(r = R(12.5), h = 10, center = true, $fn = 60);
translate([0, 0, -5]) cylinder(r = R(20), h = 5, center = true, $fn = 60);
}
//motor shaft void
scale([1.1, 1.1, 2]) motor_shaft();
//magnet voids
for (i = [0 : MAGNETS - 1]) {
rotate([0, 0, i * (360 / MAGNETS)]) {
translate([0, OFFSET, H - MAGNET_H + 1.01]) {
cylinder(r = R(MAGNET_D), h = MAGNET_H, center = true, $fn = 50);
}
}
}
//m3 nut
translate([6, 0, -9]) {
cube([2.75, 5.75, 10], center = true);
translate([0, 0, 5]) rotate([0, 90, 0]) {
cylinder(r = R(6.75), h = 2.75, center = true, $fn = 6);
translate([0, 0, 4]) cylinder(r = R(3.25), h = 20, center = true, $fn = 30);
translate([0, 0, 13.5]) cylinder(r = R(6), h = 20, center = true, $fn = 30);
}
}
}
}
module slip_coupling (MAGNET_H = 2.5) {
H = 16;
difference () {
translate([0, 0, 2]) cylinder(r = R(45), h = H, center = true, $fn = 100);
translate([0, 0, 2 -(H / 2) + (MAGNET_H + 3) / 2]) cylinder(r = R(COUPLING_D + 0.7), h = MAGNET_H + 3.01, center = true, $fn = 160);
translate([0, 0, 2 -(H / 2) + (MAGNET_H + 3) + (WASHER_H / 2)]) cylinder(r = R(WASHER_D), h = WASHER_H, center = true, $fn = 160);
translate([0, 0, 2 + (H / 2) - (5 / 2)]) cube([25, 10, 5.01], center = true);
translate([0, 0, 2 + (H / 2) - (5 / 2)]) cube([10, 25, 5.01], center = true);
//corners with voids for M3
translate([-8.75, -8.75, 2 + (H / 2) - (5 / 2)]) {
translate([0, 0, 1]) cube([(25 - 10) / 2, (25 - 10) / 2, 5.01], center = true);
cylinder(r = R(3.25), h = 20, center = true, $fn = 40);
translate([0, 0, -4.25]) hex(6, 2.75);
}
translate([8.75, 8.75, 2 + (H / 2) - (5 / 2)]) {
translate([0, 0, 1]) cube([(25 - 10) / 2, (25 - 10) / 2, 5.01], center = true);
cylinder(r = R(3.25), h = 20, center = true, $fn = 40);
translate([0, 0, -4.25]) hex(6, 2.75);
}
}
}
module daylight_spool_insert () {
translate([0, 0, 14]) reel_holder(true, false);
union () {
cube([25 - .4, 10 - .4, 5], center = true);
cube([10 - .4, 25 - .4, 5], center = true);
translate([-8.75, -8.75, 0]) difference () {
translate([.2, .2, 1/2]) cube([(25 - 10) / 2, (25 - 10) / 2, 4], center = true);
cylinder(r = R(3.25), h = 20, center = true, $fn = 40);
translate([0, 0, 2]) cylinder(r = R(5.75), h = 3.5, center = true, $fn = 40);
}
translate([8.75, 8.75, 0]) difference () {
translate([ -.2, -.2, 1/2]) cube([(25 - 10) / 2, (25 - 10) / 2, 4], center = true);
cylinder(r = R(3.25), h = 20, center = true, $fn = 40);
translate([0, 0, 2]) cylinder(r = R(5.75), h = 3.5, center = true, $fn = 40);
}
}
}
module motor_mount_void (D, Z) {
cylinder(r = R(D), h = Z, center = true, $fn = 40);
//bolt void
translate([0, 0, 5]) cylinder(r = R(3.25), h = Z + 10, center = true, $fn = 40);
translate([0, 0, 4.75]) cylinder(r = R(6), h = 3.5, center = true, $fn = 40);
}
module mount_plate_void () {
cylinder(r = R(4.25), h = 20, center = true, $fn = 40);
translate([0, 0, 0.5]) cylinder(r = R(8), h = 3, center = true, $fn = 40);
}
module mount_plate () {
Z = 1.5;
D = 7.5 + 1.5;
X = 60;
Y = 60;
MOUNT_X = 42;
MOUNT_Y = 42;
CORNER = 3;
X_CORNER = (X / 2) - (CORNER / 2);
Y_CORNER = (Y / 2) - (CORNER / 2);
//center
//color("red") cylinder(r = 15 / 2, h = 20, center = true, $fn = 60);
difference () {
translate([0, 0, 3.26 - .5]) cube([X, Y, 7], center = true);
//motor void (centered)
translate([7, 0, 0]) {
translate([-(46 / 2) + 15 + 1, 0, 0]) cylinder(r = R(15), h = 20, center = true, $fn = 60);
translate([(MOTOR_MOUNT_X / 2)+1, (MOTOR_MOUNT_Y / 2), 0]) motor_mount_void(D, Z);
translate([-(MOTOR_MOUNT_X / 2)+1, (MOTOR_MOUNT_Y / 2), 0]) motor_mount_void(D, Z);
translate([(MOTOR_MOUNT_X / 2)+1, -(MOTOR_MOUNT_Y / 2), 0]) motor_mount_void(D, Z);
translate([-(MOTOR_MOUNT_X / 2)+1, -(MOTOR_MOUNT_Y / 2), 0]) motor_mount_void(D, Z);
translate([-8 + 12.5 + 1, 0, 0]) cube([7.5, 17, Z], center = true);
}
translate([MOUNT_X / 2, MOUNT_Y / 2, 0]) mount_plate_void();
translate([-MOUNT_X / 2, MOUNT_Y / 2, 0]) mount_plate_void();
translate([MOUNT_X / 2, -MOUNT_Y / 2, 0]) mount_plate_void();
translate([-MOUNT_X / 2,-MOUNT_Y / 2, 0]) mount_plate_void();
translate([X_CORNER, Y_CORNER, 3.26 - .5]) cube([CORNER, CORNER, 8], center = true);
translate([-X_CORNER, Y_CORNER, 3.26 - .5]) cube([CORNER, CORNER, 8], center = true);
translate([X_CORNER, -Y_CORNER, 3.26 - .5]) cube([CORNER, CORNER, 8], center = true);
translate([-X_CORNER, -Y_CORNER, 3.26 - .5]) cube([CORNER, CORNER, 8], center = true);
}
translate([X_CORNER - (CORNER / 2), Y_CORNER - (CORNER / 2), 3.26 - .5]) cylinder(r = CORNER, h = 7, center = true, $fn = 40);
translate([-X_CORNER + (CORNER / 2), Y_CORNER - (CORNER / 2), 3.26 - .5]) cylinder(r = CORNER, h = 7, center = true, $fn = 40);
translate([X_CORNER - (CORNER / 2), -Y_CORNER + (CORNER / 2), 3.26 - .5]) cylinder(r = CORNER, h = 7, center = true, $fn = 40);
translate([-X_CORNER + (CORNER / 2), -Y_CORNER + (CORNER / 2), 3.26 - .5]) cylinder(r = CORNER, h = 7, center = true, $fn = 40);
}
//centered, minimal geometry needed to add
//58x52
module minimal_mount () {
difference () {
mount_plate();
translate([50 + 29, 0, 0]) cube([100, 100, 100], center = true);
translate([-50 - 29, 0, 0]) cube([100, 100, 100], center = true);
translate([0, 50 + 26, 0]) cube([100, 100, 100], center = true);
translate([0, -50 - 26, 0]) cube([100, 100, 100], center = true);
}
}
module debug_assembled () {
translate([(46 / 2) - 14.5, 0, 0]) rotate([180, 0, 0]) geared_motor();
color("green") translate([0, 0, 11]) mount_plate();
color("blue") translate([0, 0, 23]) rotate([0, 0, -90]) //magnetic_coupling();
difference () {
translate([0, 0, 26.5]) slip_coupling();
translate([-50, 0, 0]) cube([100, 100, 150], center = true);
}
color("red") translate([0, 0, 34]) daylight_spool_insert();
}
PART = "mount_plate";
if (PART == "slip_coupling") {
slip_coupling();
} else if (PART == "magnetic_coupling") {
magnetic_coupling();
} else if (PART == "mount_plate") {
//42x42 M4 mounting holes
mount_plate();
} else if (PART == "daylight_spool_insert") {
daylight_spool_insert();
} else if (PART == "minimal_mount") {
minimal_mount();
} else if (PART == "debug") {
debug_assembled();
}

68
src/alert/index.ts Normal file
View File

@ -0,0 +1,68 @@
'use strict';
import { delay } from 'delay'
/* class representing alert functionality */
class Alert {
private ipc : any
private log : any
private id : string = 'alert'
private cb : Function = null
private ui : any
constructor ( ui : any) {
this.ui = ui
this.init()
}
/**
*
**/
private async init () {
const Log = require('log')
this.log = await Log({ label : this.id })
this.ipc = require('electron').ipcMain
this.listen()
}
/**
*
**/
private listen () {
this.ipc.on(this.id, this.listener.bind(this))
}
/**
*
**/
private async listener (event : any, arg : any) {
if (this.cb !== null) {
try {
await this.cb(arg.state, arg.id)
} catch (err) {
this.log.error(err)
}
}
event.returnValue = true
}
/**
*
**/
public async start (cmd : string) {
const start = +new Date();
const msg : string = (cmd + '').replace('ALERT', '').replace('Alert', '').replace('alert', '').trim()
this.ui.send(this.id, { msg })
return new Promise(function (resolve : Function, reject : Function) {
this.cb = function () {
const ms = (+new Date()) - start;
return resolve(ms);
}
}.bind(this));
}
}
module.exports = function (ui : any) {
return new Alert(ui);
}

View File

@ -3,11 +3,11 @@
//import Log = require('log');
import { delay } from 'delay';
const SerialPort = require('serialport')
const Readline = SerialPort.parsers.Readline
const { SerialPort } = require('serialport')
const { ReadlineParser } = require('@serialport/parser-readline')
const exec = require('child_process').exec
const parser : any = new Readline('')
const parser : any = new ReadlineParser({ })
const newlineRe : RegExp = new RegExp('\n', 'g')
const returnRe : RegExp = new RegExp('\r', 'g')
@ -108,7 +108,6 @@ class Arduino {
//console.error(err)
return reject(err)
}
//
})
})
}
@ -198,9 +197,10 @@ class Arduino {
async connect (serial : string, device : string, confirm : any) {
return new Promise(async (resolve, reject) => {
let connectSuccess : any
this.path[serial] = device;
this.alias[serial] = device;
this.serial[device] = new SerialPort(this.path[serial], {
this.path[serial] = device
this.alias[serial] = device
this.serial[device] = new SerialPort({
path : this.path[serial],
autoOpen : false,
baudRate: cfg.arduino.baud,
parser: parser
@ -252,7 +252,12 @@ class Arduino {
|| data === cfg.arduino.cmd.camera_second_forward
|| data === cfg.arduino.cmd.camera_second_backward
|| data === cfg.arduino.cmd.camera_second
|| data === cfg.arduino.cmd.cameras) {
|| data === cfg.arduino.cmd.cameras
|| data === cfg.arduino.cmd.capper_identifier
|| data === cfg.arduino.cmd.camera_capper_identifier
|| data === cfg.arduino.cmd.camera_capper_projector_identifier
|| data === cfg.arduino.cmd.camera_capper_projectors_identifier) {
this.confirmExec(null, data);
this.confirmExec = {};
@ -314,12 +319,23 @@ class Arduino {
type = 'camera,camera_second,projector'
} else if (data === cfg.arduino.cmd.cameras_projectors_identifier) {
type = 'camera,camera_second,projector,projector_second'
} else if (data === cfg.arduino.cmd.capper_identifier) {
type = 'capper'
} else if (data === cfg.arduino.cmd.camera_capper_identifier) {
type = 'camera,capper'
} else if (data === cfg.arduino.cmd.camera_capper_projector_identifier) {
type = 'camera,capper,projector'
} else if (data === cfg.arduino.cmd.camera_capper_projectors_identifier) {
type = 'camera,capper,projector,projector_second'
}
return resolve(type)
}
await delay(cfg.arduino.serialDelay)
try {
writeSuccess = await this.sendAsync(device, cfg.arduino.cmd.mcopy_identifier)
this.log.info(writeSuccess)
} catch (e) {
return reject(e)
}
@ -344,7 +360,9 @@ class Arduino {
write : async function (cmd : string, cb : any) {
const t : any = {
c : cfg.arduino.cam.time + cfg.arduino.cam.delay,
p : cfg.arduino.proj.time + cfg.arduino.proj.delay
p : cfg.arduino.proj.time + cfg.arduino.proj.delay,
A : 180,
B : 180
}
let timeout : number = t[cmd]
if (typeof timeout === 'undefined') timeout = 10

View File

@ -9,7 +9,8 @@ import { delay } from 'delay';
class Camera {
private state : any = {
pos : 0,
dir : true
dir : true,
capepr: false
};
private arduino : Arduino = null;
private intval : any = null;
@ -87,6 +88,28 @@ class Camera {
return await this.end(cmd, id, ms);
}
/**
*
**/
public async cap (state : boolean, id : string) {
let cmd : string;
let ms : number;
if (state) {
cmd = this.cfg.arduino.cmd[`${this.id}_forward`];
} else {
cmd = this.cfg.arduino.cmd[`${this.id}_backward`];
}
this.state.capper = state;
try {
ms = await this.arduino.send(this.id, cmd);
} catch (err) {
this.log.error(err);
}
return await this.end(cmd, id, ms);
}
/**
*
**/
@ -189,20 +212,26 @@ class Camera {
private async listener (event : any, arg : any) {
if (typeof arg.dir !== 'undefined') {
try {
await this.set(arg.dir, arg.id);
await this.set(arg.dir, arg.id)
} catch (err) {
this.log.error(err);
this.log.error(err)
}
} else if (typeof arg.frame !== 'undefined') {
try {
await this.move(arg.frame, arg.id);
await this.move(arg.frame, arg.id)
} catch (err) {
this.log.error(err);
this.log.error(err)
}
} else if (typeof arg.val !== 'undefined') {
this.state.pos = arg.val;
this.state.pos = arg.val
} else if (typeof arg.capper !== 'undefined') {
try {
await this.cap(arg.capper, arg.id)
} catch (err) {
this.log.error(err)
}
}
event.returnValue = true;
event.returnValue = true
}
/**

Some files were not shown because too many files have changed in this diff Show More