Merge pull request 'Merge in 9 months of work on capper branch' (#71) from capper into main

Reviewed-on: #71
This commit is contained in:
Matt McWilliams 2023-02-19 00:28:45 -05:00
commit c5e66a6f40
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

@ -45,6 +45,8 @@
<div id="camera_second_backward" class="row cam2" y="2"></div>
<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>
@ -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":"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"}

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;
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)
}
cmd = require('cmd')(cfg, proj, cam, light, cam2, proj2)
if (dev && dev.connected && dev.connected.capper) {
capper = require('capper')(arduino, cfg, mainWindow.webContents, filmout, true)
}
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

@ -81,12 +81,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
@ -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')
@ -122,7 +137,8 @@ class Grid {
'camera_backward',
'camera_second_backward',
'projector_backward',
'projector_second_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

@ -29,4 +29,110 @@ module trap_cube(height = 19, top_x = 30, top_y = 34, bottom_x = 45, bottom_y =
cube([bottom_x - wall_thickness, bottom_y - wall_thickness, 0.1], center=true);
}
}
}
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