Variable pull distance programmed with Js

Hello,
I typically program robotics and/or machinery, so I’m very new to Js.
The company I work for has this machine that I need to get up and running.
In order to have it do the math, I need to learn, at least, the basics, of Js.

That’s all well and good, but my problem is this:

I’m pulling parts onto a roll and they need to be evenly spaced.
My understanding is that my pull distance will change by twice the thickness of the parts every time the machine makes a full rotation. We have a sensor that tells the machine when a rotation has been completed.

Does anyone have any advice for learning Js in general and/or any tips for how to code this specific math problem?

Firstly, welcome to the forums.

While we are primarily here to help people with their Free Code Camp progress, we are open to people on other paths, too. Some of what you are asking is pretty trivial in the Free Code Camp context, so you might find that the FCC curriculum will really help you get started. At a modest guess I’d say investing a 4-5 hours working through the curriculum here will really pay off. You can find the curriculum at https://www.freecodecamp.org/learn.

With your current questions, we don’t have enough context to know what you already know or don’t know, so it is impossible to guide you.

It is pretty typical on here for people to share a codepen / repl.it / jsfiddle example of what they have tried so that anyone helping has more of an idea of what help is actually helpful.

Please provide some example of what you’ve tried and I’m sure you’ll get more help.

Happy coding :slight_smile:

Thanks for the warm welcome, and the speedy response.

I’ve gone through a good chunk of the introductory course, and have tested a few simple formulas. (i.e. circumference calculator, etc)
I will continue the course regardless, as I find coding interesting and it can’t hurt to, at least try and, add another tool to my box.

To refine my question, I need the arc length to equal 30mm regardless of my diameter. Given my givens, I can calculate my pull angles for a given number of rotations(on paper). However, I cannot tell the machine to pull a certain number of degrees(only mm), and I am at a loss on how to translate that into Js.

I can account for the increasing diameter using my sensor with something like this:

function circ(rollHome, d) {
  if (rollHome >= 3) {
    return Math.PI * (d + (rollHome + 3));
  } else {
    return Math.PI * d;
  }
}
console.log(circ(4, 93));

First number in the call out would simply be tied to variables that keep track of sensor input, while the 93 is my starting diameter, which I should probably tie to a const.
Also, the less than 3 part is arbitrary at this point, but that seems straight forward to modify.

The only thing I can think to do is something where I lay out each and every case, given the rollHome count, and use this to assign my pull distance. This sounds doable, but painful. Granted, my total number of rotations is under 20.

I’m not expecting any miracles here, just hoping I’m missing something that could simplify this function.

From what I follow, it sounds like you’re trying to figure out the equation and the code at the same time? If you can iron out the physics system of equations first, that can be translated into JavaScript.

I’m not sure what mechanical process you’re writing a controller for (and it’s been a loooong time since I was in Physics 101), or how precisely you have to control tension in the winding proccess. With a constant thickness of the material and a constant diameter of the cylinder being wrapped, you can calculate the rate of change of the spiral’s radius. Then, based off the configuration of the equipment, you should be able to convert that to a rate of change for the mechanism you are controlling.

You mentioned only being able to measure or control the length of an arc. If the total circumference is calculated, then converting that to radians for the .Math functions is straightforward.

__
This is definitely outside of my wheelhouse, but hopefully some of that was vaguely useful.

Ok,

Here’s what I have on the math end.

The formula for arc length is arc length = 2 π r (θ/360°)
substituting our initial diameter for 2r, plugging in our desired arc length (30mm), and rearranging the formula to calculate the angle, we get this formula: (30/(93 * pi) *360 = degrees of rotation. This gives us an angle just shy of 37 degrees.
so **(desired arc length/circumference) *360

Now we get a spread sheet and we calculate the angle what we get for the arc length of 30mm with a given diameter, and we see that the angle decreases as the diameter increases, which makes sense. The diameter increases by 6mm every 360 degrees of rotation, causing the angle of rotation to decrease in a non-linear fashion.

We then determine the mm/degree of the motor with: (pi * wheel diameter)/360. Which I can now use to tell the motor to move x number of degrees, I think.

We can then take our desired angle and convert it to a pull distance with the mm/degree = 30. Or, 30/degree gives us our mm to pull.

In other words, we calculate the angle that gives us the desired arc length, and then divide 30 by that angle.

If anyone sees a mistake there, please let me know.
My next post will be my attempt to translate this calculation into javascript.

let rh = 4 //rollhome *sensor input*
const sd = 93  //starting roll diameter
const wc = Math.PI * 88.9254  //motor wheel circumference
const al = 30 //desired arc length

//current roll circumference
function cc(rh, sd) {
  if (rh >= 3) {
    return Math.PI * (sd + ((rh - 2)*6));
  } else {
    return Math.PI * sd;
  }
}
c = cc(rh,sd);
//pullcalc
function pull(al,cc,wc) {
  return (al / cc) *wc;
}

console.log(cc(rh,sd));
console.log(pull(al,c,wc));

Ok, my math was wrong, but I think I figured it out.
At the end of the day, I only need to track my current circumference.
Once that is done, it’s just (desired arc length * motor wheel circumference) / current circumference.

I don’t need the angle! It’s basically a changing gear ration, or something like that.

Anyways, this set of functions works for any given input to rh (rollhome sensor input)

Anybody have any suggestions?

Congratulations on figuring it out! In coding, as in life, the hardest part is often figuring out what problem actually needs solving.

My only feedback would be to use more descriptive variable names. 1-2 letter variable names are traditional, but do future maintainers on this code a favor and make it a little easier to grok what the functions are doing.

I’ve edited your code for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (').

Noted.
Thanks for the tip and support.

I’ve transferred the code into the machinelogic system. In which, the labels are different.
I basically had to deconstruct it so that the variables and the code are actually on separate pages, and there’s only about 6 lines that are actually written in javascript. Two for the math, and four or so for the if statement that lines the current circumference up with reality by tracking the number of full rotations via a sensor.
It stays at the starting circumference until x number of rotations, then begins adding the material thickness to the diameter. This is because the parts travel a distance before interacting with the roll.

This was actually a cool conversation for me to have because my dayjob is writing tools for industrial automation. Having converstations about what automation engineers are programming machinery to do is a neat opportunity for me.

That’s awesome! This was fun for me as well, believe it or not.

I have another question…or two.
I think I know the answer, but I’d rather double check.

It should be noted that this code will be going into block code that runs python in the background, so I’ll have to work with the company that designed this block coding on the exact way to break these functions apart.
I figure it would be good to make sure the code is written properly and works as intended before I deconstruct it to put it into the block code.

Question 1:
If one of my arguments is a constant, could I simply put the number in the function, or do I first need to assign the value to a var, let, or const and then use that assigned value as one of the arguments?

Question 2:
Since I’m calling the first function (currentCircumference) in the second one(pullDistance) would I call just the label, or do I need the parenthesis, or do I need the parenthesis with the original arguments in there as well.

for example:

Should my arguments be set up like this?
(rollHome would be tracking a sensor input that counts the number of complete rotations)

const startingDiameter = 93
const motorWheelCircumference = Math.PI * 88
const desiredArcLength = 30


function currentCircumference(rollHome, startingDiameter) {
  if (rollHome >= 3) {
    return Math.PI * (startingDiameter + ((rollHome - 2)*6));
  } else {
    return Math.PI * startingDiameter;
  }
}

function pullDistance(desiredArcLength, currentCircumference, motorWheelCircumference) {
  return (desiredArcLength / currentCircumference) * motorWheelCircumference;
}

console.log(pullDistance())

or like this:

function currentCircumference(rollHome) {
  if (rollHome >= 3) {
    return Math.PI * (93 + ((rollHome - 2)*6));
  } else {
    return Math.PI * 93;
  }
}

function pullDistance(currentCircumference) {
  return (30 / currentCircumference) * (Math.PI * 88);
}

console.log(pullDistance())

As far using a previous function as an argument in a new function, should I call it like this?

function pullDistance(currentCircumference) {
  return (30 / currentCircumference) * (Math.PI * 88);
}

Like this?

function pullDistance(currentCircumference()) {
  return (30 / currentCircumference()) * (Math.PI * 88);
}

or like this?

function pullDistance(currentCircumference(rollHome)) {
  return (30 / currentCircumference(rollHome)) * (Math.PI * 88);
}

This is going to be one of the cases where it’s fine to “break the rules” if it makes sense for your specific use case. Here, you’re programming for a specific piece of hardware that (presumably) will always have the same starting circumference, so hardcoding that in the function wouldn’t be atypical. As a best practice, I would suggest having a “constants” file that your function(s) pull from. In theory this supports making changes like replacing a part with different specs or changing the desired arc length. It can provide a cleaner organization structure. But with something like this I would prioritize workplace/industry conventions. In other words, ask someone how they would normally approach that.

If you are using currentCircumference as a function, then you’ll want to call it as a function. If it is in (or exported to) the same scope as pullDistance, then you don’t need to pass it as a parameter. That would look something like this:

function pullDistance(desiredArcLength, motorWheelCircumference) {
const rollHome = getRollHome(); // or however you get this value
const startingDiameter = getStartingDiameter(); // or however you get this value
return (desiredArcLength / currentCircumference(rollHome, startingDiameter)....

However, because your currentCircumference is not dependent on the same values as pullDistance, it would be more common to call that function first and pass the result of it into pullDistance function as a value.

That would look something like this:

function currentCircumference(rollHome, startingDiameter) {
  if (rollHome >= 3) {
    return Math.PI * (startingDiameter + ((rollHome - 2)*6));
  } else {
    return Math.PI * startingDiameter;
  }
}

function pullDistance(desiredArcLength, currentCircumference, motorWheelCircumference) {
  return (desiredArcLength / currentCircumference) * motorWheelCircumference;
}
....
const currCirc = currentCircumference(rollHome, startDiam);
return pullDistance(desiredArc, currCirc, wheelCirc)

Also, these same functions could be written in Python, if that makes everything less complicated. They would look almost the same.

I’m fairly certain that I will need to set up my const and any other variables on the “variable” page, and then call them into the “lambda” functions that use java.
I don’t think I can access the python section of the block coding without doing the entire thing in python. While I would prefer that, it is not my decision since it is not my project and timelines have already not been met.

I am waiting on a response from someone at the company that sold us the system to answer some questions. Which is why I currently have the “circ” set to the “currentCirc(rollHome, startingDiam)” function after the function. Again, still waiting on answers. It would be nice if I could combine these two into one lambda function, but that’s just my OCD and I’m not sure their system will support that sort of thing.

I really like the point you made about not hardcoding any values in, so that they could be changed quickly if ever needed. Heaven forbid the motor breaks and the replacement has a different wheel circumference.

I have a Javascript sandbox I’ve been using to test outputs based for a given “rollHome” input. It has been matching up with an excell spreadsheet. I just change the “rollHome” value and compare the two.

How did you highlight the names of the functions? That seems more legible than my quotes.

With your help, this is what I have so far:

let rollHome = 2 //*sensor input*
const startingDiam = 93 
const motorWheelCirc = Math.PI * 88.9254 
const desiredArcLength = 30 


function currentCirc(rollHome, startingDiam) {
  if (rollHome >= 3) {
    return Math.PI * (startingDiam + ((rollHome - 2)*6));
  } else {
    return Math.PI * startingDiam;
  }
}

let circ = currentCirc(rollHome, startingDiam);  


function pullDistance(circ, desiredArcLength, motorWheelCirc) {
  return (desiredArcLength / circ) *motorWheelCirc;
}

console.log(currentCirc(rollHome, startingDiam));
console.log(pull(circ, desiredArcLength, motorWheelCirc)));

That looks pretty much how I would code it up (but with the constants coming from a variables file, as you mentioned).

Single ticks (` inline code ` ).

Awesome, thank you very much.