Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added connect to Pi button #103

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

sidntrivedi012
Copy link
Member

Adding the static button as of now. In this thread will work on #75.
/cc : @jywarren @starkblaze01 @Dhiraj240 @harshithpabbati

@jywarren
Copy link
Member

Awesome!!!

@sidntrivedi012
Copy link
Member Author

Hey, I have added the following code from Infragram to the example file of capture. It can be found here - https://github.com/sidntrivedi012/spectral-workbench.js/blob/pi-button/examples/capture/index.html#L363-L380 . Have also included the infragram.js lib here.

But, when I run index.html file of capture, it shows the following error -

Screenshot 2019-07-18 at 2 05 29 AM

Any suggestions how to resolve it? Thanks :)

/cc: @jywarren @starkblaze01 @harshithpabbati @Dhiraj240

@sidntrivedi012
Copy link
Member Author

I have added the following code to index.html in the examples/capture directory. But the error of event being null still persists. Any suggestion how to resolve this?

    var infragram, boost, openInSequencer;
    document.getElementById("pibutton").onclick=function connect_to_pi(){
    //infragram code to connect to raspberry-pi
      infragram = Infragram({
        uploader: false,
        processor: 'webgl',
        shaderVertPath: "../../node_modules/dist/shader.vert",
        shaderFragPath: "../../node_modules/dist/shader.frag"
      });
      var piImage = new Image();
      piImage.onload = function () {
        infragram.options.processor.updateImage(piImage);
      };
      var fetchImageInterval = setInterval(function fetchImage() {
        // piImage.src = "http://pi.local/cam/cam_pic.php?time=" + new Date().getTime();
        piImage.src = "../logo.png";
      }, 50);
    };

if(el){
//if pi_div button does not return null
document.getElementById("pi-button").addEventListener("click", function connect_to_pi() {
infragram = Infragram({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, actually i don't think it's necessary to include all of Infragram here, but we can simply borrow the appropriate sections of code! Actually all we want is the function that fetches an image from the Pi. Let me highlight.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Removing infragram initialisation from here.

};
var fetchImageInterval = setInterval(function fetchImage() {
// piImage.src = "http://pi.local/cam/cam_pic.php?time=" + new Date().getTime();
piImage.src = "../logo.png";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:-) you've got this part right!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks 🎉

});
var piImage = new Image();
piImage.onload = function () {
infragram.options.processor.updateImage(piImage);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So here, instead of instantiating Infragram, we should add the image to the SWB canvas, so it gets grabbed and sent to the graph.

$W.ctx.drawImage(piImage, 0, 0, $W.width, 1); // this will draw it to the waterfall canvas

The only problem here is that it's actually drawing the WHOLE camera's output, squishing it to 1 pixel tall. So, see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage

Instead let's crop the source image dimensions too!

Suggested change
infragram.options.processor.updateImage(piImage);
var sourceX = 0, sourceY = 0, sourceHeight = 300, sourceWidth = 800; // although we may modify these later to match the Pi output image dimensions
$W.ctx.drawImage(piImage, sourceX, sourceY, sourceHeight, sourceWidth, 0, 0, $W.width, 1); // this will draw it to the waterfall canvas

However, it seems we may also need to stop this from getting images from the webcam:

onSave: function (data) {

So, we ought to add a conditional there that checks for a new property $W.loadingFromPi, and when you click that button we'll set that to true -- that way it no longer pulls from the webcam, make sense?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jywarren I have added a condition to onSave:

onSave: function(data) {
      if ($W.loadingfromPi == false) {
           <onSave code snippet>
      }
},

And assigned default value to loadingfromPi to false. I am setting the value of it to true when the button is being clicked.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you just push up your latest code when you have a chance? Thanks!

package.json Outdated
"getusermedia-js": "~1.0.0",
"d3": "~3.4.0"
"infragram": "^0.2.1",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we can remove this too!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, removing it. Thanks.

@jywarren
Copy link
Member

Hi @sidntrivedi012, any updates here? Thank you!!!

@jywarren
Copy link
Member

Oh sorry, i see you responded yesterday. Thanks!

@sidntrivedi012
Copy link
Member Author

sidntrivedi012 commented Jul 23, 2019

@jywarren , Apologies for the delay. Have tried to fix the loopholes as pointed by you. Also, bumped some dependencies except flot since the demo was showing ERR:file not found errors with the newer version of flot. PTAL. Thanks. 🙂

/cc: @starkblaze01 @Dhiraj240 @harshithpabbati

@jywarren
Copy link
Member

Were you able to try putting this up on your own gh-pages so we can try it out live? That would be great!

@jywarren
Copy link
Member

you'll have to add the node modules to the gh-pages branch and push them up too, without adding them to your main branch. It's a little finicky, but give it a try!

@sidntrivedi012
Copy link
Member Author

sidntrivedi012 commented Jul 29, 2019

@jywarren , Have pushed the code to fork's gh-pages branch. Can be seen here - https://sidntrivedi012.github.io/spectral-workbench.js/examples/capture .

@sidntrivedi012
Copy link
Member Author

Copy link
Member

@jywarren jywarren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I traced this a bit and found that there's a second place the image is being copied, this time to the preview window. It may not be the only issue, because i see that the graph is also not sourcing from the pi image... let me keep looking, but this definitely will help!

@jywarren
Copy link
Member

jywarren commented Aug 2, 2019

So, the broader issue here is that there are references to $("video")[0] throughout -- and uses of video or window.video both of which reference that same <video> element.

What we need, I think, is to make a new function called $W.getVideoEl(), which contains the conditional, so:

function getVideoEl() {
  if ($W.loadingfromPi) return $W.piImage;
  else return $("video")[0];
}

Note I'm using the property $W.piImage instead of the locally defined piImage, as in my earlier comment, so that change will have to happen too.

Does this make sense, @sidntrivedi012 ? It's a change throughout the file, but then you'll be able to change any reference to the original video element to instead be to $W.getVideoEl() which will route correctly.

@jywarren
Copy link
Member

jywarren commented Aug 14, 2019 via email

@sidntrivedi012
Copy link
Member Author

@jywarren Can you please review it now? I have made the changes as suggested by you.

@jywarren
Copy link
Member

Hi, Siddhant, i'm not seeing the static image load when I press Connect. Can you look and try to figure out why? Thanks!

@sidntrivedi012
Copy link
Member Author

Sure, looking into it.

@sidntrivedi012
Copy link
Member Author

So, the broader issue here is that there are references to $("video")[0] throughout -- and uses of video or window.video both of which reference that same <video> element.

What we need, I think, is to make a new function called $W.getVideoEl(), which contains the conditional, so:

function getVideoEl() {
  if ($W.loadingfromPi) return $W.piImage;
  else return $("video")[0];
}

Note I'm using the property $W.piImage instead of the locally defined piImage, as in my earlier comment, so that change will have to happen too.

Does this make sense, @sidntrivedi012 ? It's a change throughout the file, but then you'll be able to change any reference to the original video element to instead be to $W.getVideoEl() which will route correctly.

Hey @jywarren , can you please guide me how and where to use this function? I mean where will this function be called?

@jywarren
Copy link
Member

Basically all the instances of $("video")[0], video or window.video reference the same <video> element, but it's quite messy how it's set up. So you should replace all instances of that throughout the file with a standard method getVideoEl(). That way, you can switch between the Pi sample image and the true webcam all in one place, since all references to the video element will be routed through that function. Make sense?

@sidntrivedi012
Copy link
Member Author

sidntrivedi012 commented Aug 22, 2019

Basically all the instances of $("video")[0], video or window.video reference the same <video> element, but it's quite messy how it's set up. So you should replace all instances of that throughout the file with a standard method getVideoEl(). That way, you can switch between the Pi sample image and the true webcam all in one place, since all references to the video element will be routed through that function. Make sense?

@jywarren window.video is being used only once in capture.js here -


I was thinking to hard code a conditional here. Just to ask, what should we insert here if the image is being loaded from the Pi?

if(getVideoEL()==$("video")[0]) window.video=video;
else <<what to use here?>>

Regarding the rest, I think we can easily use a function as suggested by you.

@jywarren
Copy link
Member

You can do window.video - getVideoEl() at that spot.

The function should be:

function getVideoEl() {
  if ($W.loadingfromPi) return $W.piImage;
  else return $("video")[0];
}

That way it returns an image or video element no matter where you call it from. Make sense?

@sidntrivedi012
Copy link
Member Author

@jywarren Its somewhat working. Also have made some changes in the code. Will push in a new commit. PTAL. Thanks.
pibutton

The problem now is that the page is distorting when one clicks connect to Pi.

@jywarren
Copy link
Member

I think the distortion is OK; it's mapping the aspect ratio of the source image to the area available for display. This won't affect the spectrum. Is this ready then? Let's merge it!

@sidntrivedi012
Copy link
Member Author

sidntrivedi012 commented Aug 23, 2019

@jywarren But there's a problem that unfortunately the live plot has shifted downwards.
pibutton2

@jywarren
Copy link
Member

I think you may have updated to Bootstrap 4 somehow? And that is affecting the styling?

@sidntrivedi012
Copy link
Member Author

@jywarren Nope, I didn't upgrade to Bootstrap 4. Maybe there's something else. Will debug it. Thanks.

@sidntrivedi012
Copy link
Member Author

@jywarren Also, there's one more problem that even when the image is being loaded from the Pi, the plot still gets made of the image from the camera.

So, as of now there are two problems :

  • Adjustment of the canvas plot.
  • Plotting of the data from Pi when connected to Pi instead of the device camera

@sidntrivedi012
Copy link
Member Author

@jywarren Since this thread has become very long, should we tackle the two issues(as mentioned in the above comment) emerging due to the connect to Pi feature in another PR?

@sidntrivedi012
Copy link
Member Author

sidntrivedi012 commented Aug 28, 2019

@jywarren You were right. I had upgraded bootstrap from 3.4.0 (currently being used) version to 4.3.0 . And thus, maybe the plot was being formed on the lower end. But when I installed the 3.4.0 version of bootstrap again. The video capturing stopped.

@sidntrivedi012
Copy link
Member Author

videonotworking
@jywarren This is happening from when I downgraded the version of bootstrap. Don't know why. Searching it out. Do you have any idea why this may be occuring?

@jywarren
Copy link
Member

jywarren commented Aug 28, 2019 via email

@sidntrivedi012
Copy link
Member Author

@jywarren Nah, no errors in the console.

@jywarren
Copy link
Member

I would use the Element inspector to see if the proper canvas or video element is being displayed under the area in question. Perhaps some CSS has gone wrong? Or, can you confirm that all libraries are installed with npm install ?

@sidntrivedi012
Copy link
Member Author

@jywarren Have checked all the libraries and installed them with npm install. Don't know what's going wrong. Also, no error is being displayed in the console. Will debug it today and send a patch by evening surely.

@sidntrivedi012
Copy link
Member Author

cameraworking

@jywarren Its working now. PTAL.

@jywarren jywarren mentioned this pull request Jul 27, 2021
30 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants