Skip to content
This repository has been archived by the owner on Feb 8, 2024. It is now read-only.

Convert internal distance units to millimeters #176

Open
Wackerbarth opened this issue Jan 17, 2019 · 18 comments
Open

Convert internal distance units to millimeters #176

Wackerbarth opened this issue Jan 17, 2019 · 18 comments

Comments

@Wackerbarth
Copy link
Contributor

Internally, using meters as the fundamental unit of measure is inappropriate because it is not of the actual scale of the devices that we target and, more importantly, it is not the industry standard for communication with the user.

By adopting the industry standard (millimeter) as the fundamental unit of distance we avoid many internal conversions and avoid having the values seen in our configuration files in a different form from that which the user sees when interacting with the printer.

@zaped212
Copy link
Contributor

One of the things that I have enjoyed about this project is that it uses standard SI units.
To me that makes reading the configuration file alot easier as the units are well known and understood.

Yes this might introduce a bit of extra processing to internally convert to units being used indie the code but we have alot of processing power and the conversions are pretty negligible on lower systems anyways.

If conversion is the concern I wonder if it would be cleaner to leave SI units in the config and update the internal code to use SI units instead of converting to mm, and the like.

@Wackerbarth
Copy link
Contributor Author

Well, @zaped212, perhaps it makes sense to you that the units in the configuration are different units from the units used in the commands that set them. However, many are confused about which units to use where. And SI units provide absolutely no advantage in terms of the computations because we are concerned only with distance and time. So, from the view of clarity, using the industry standard, which also is better scaled to the equipment, helps. And I would argue that, for most users, SI units are NOT as well known, or understood, in this community.

@goeland86
Copy link
Member

@Wackerbarth speak for yourself about SI unit familiarity.
The community at large is not US-based, and quite familiar with the entirety of the metric system on a daily basis.

Regarding the change to another unit - I think it's correct to assume we should have a single unit all the way through - from config to processing - where possible. I'm assuming there are cases with a delta where numerical precision would suffer if we were to keep everything in meters. However, the precision loss will likely be negligible compared to a similar system running even an ARM v6 chip, as the ARMv7 has a hard-float FPU attached, therefore making such computations both faster and more precise.

The project denotes itself specifically for its use of the SI system, and this is something that, once explained and understood, makes sense to all users. To change it back now would be a disaster in terms of both config upgrades and communication to users.

So I would really prefer if the config stayed in SI and we instead matched the SI system to other parts of the system with as few casts down to smaller units as necessary.

If we're able to have a clear and consistent config (i.e. convert "steps_per_mm" to "steps_per_m") and properly propagate the SI units through the code, it means that Redeem's potential to handle precise & large machinery just went up exponentially.

@Wackerbarth you keep thinking in terms of desktop printers, without realizing that printers in the future could be bigger than a 747's hangar bay, and a mm-based firmware would end up hitting the upper-limit an integer. While a small inconvenience for us now, it's nowhere near that big of an issue as you make of it for the community at large.

@Wackerbarth
Copy link
Contributor Author

Yes, I think in terms of desktop printers and CAM because that’s the kind of machinery that uses Marlin compatibility. If you want larger units you will likely change the programming language

@goeland86
Copy link
Member

Which is planned once OctoPrint allows us to communicate via socket instead of serial port, if I recall correctly. Admittedly we still have the issue of slicers generating gcode in mm, but that's something we can tackle when we have the socket working.

@Wackerbarth
Copy link
Contributor Author

If you are concerned about scalable configuration, try using “steps per unit distance” and the actual units fall out of the equation

@goeland86
Copy link
Member

I don't follow. What do you mean "steps per unit distance" - you need to specify a distance unit for the printer configuration to make sense, or you're going to end up with a disaster.

@Wackerbarth
Copy link
Contributor Author

Wackerbarth commented Jan 21, 2019 via email

@Wackerbarth
Copy link
Contributor Author

When I commented about lack of familiarity with SI, I was referring to units other than distance and its time derivatives. SI is clearly advantageous when you start mixing in momentum, energy, etc. But, in my experience, most individuals have little concept of those topics, in any system of units. Admittedly in the US we have limited use for any metric units other than mm.

@RaveGun
Copy link

RaveGun commented Jan 22, 2019

As much as I enjoy reading this chat on the issues this is just stopping the evolution.

"@Wackerbarth you keep thinking in terms of desktop printers, without realizing that printers in the future could be bigger than a 747's hangar bay, and a mm-based firmware would end up hitting the upper-limit an integer. "

This is quite wrong in two aspects:

  1. Max integer in mm is equal to over 2000km.

  2. And if you are talking about the user base then, I dare you to find some using this on a printer, no, even easier, on a thing that is larger than 2m.

I have a question: what is now the standard in the slicers that we use?

We can have two parameters:

  • redeem distance units
  • slicer distance units

Then we will cover everybody.

@Wackerbarth
Copy link
Contributor Author

@RaveGun -- As I read your response, (1) You indicate that even expressing ALL distances in integer mm would more than cover any feasible mechanical situation. (And that ignores the fact the we could use "scientific notation" to input ANY floating value -- Not that I would advocate doing so.) Therefore the "747 hanger bay" argument is a false argument against the technical use of mm as the fundamental unit.

(2) The standard in slicers is clearly mm.

(3) Having "Redeem distance units" and "Slicer distance units" is somewhat the current situation. And the source of confusion. A typical printer bed is 200mm, the slicer sees it as 200mm, but redeem sees it as 0.2m. If the inputs included units in addition to a numeric value, then the user could express the size in either way and, internally, the system could use ANY unit that it desires.

My point is that, because distances are input and output as numbers, without the associated units, a consistent unit of measure should be used throughput. And, that scale factor, whatever it is, actually "falls out" of all the math. Thus, my concrete extruder could operate in "feet" because I have described the motion in steps_per_foot rather than steps_per_mm. And "g0 X8" might move the nozzle the width of a typical small room. That what I meant by "steps_per_unit_distance". In a strongly typed programming language, all of the unit conversion could be handled by the compiler. But our input language (G-code), output, and internal programming are all weakly typed.

@goeland86
Copy link
Member

But our input language (G-code), output, and internal programming are all weakly typed.

Uh. No. Python is a weakly typed language. GCode is strongly typed - you can't say G1 Xa for instance - it demands a numerical value. Where a weakly typed language would allow it. A strongly typed language would instead require something like command:G1, axis = X, dist = {8, mm}

I get your point, but at the same time, until we have enough adoption to push for an improvement on the standard gcode description, we have to assume slicers will keep pushing units in mm. That or we need to create a "Redeem-enhancer" that takes a typical slicer's output and adds a unit on every axis move that is defined in the output.

What @RaveGun is saying in regards to redeem vs slicer units actually makes sense to declare it clearly. Some slicers and firmwares expect units in inches instead of mm - so it's not unreasonable to think it would need explicit clarification. You say the same thing that if we had the units in the config file, all confusion would be lost and I agree. However the "steps_per_mm" vs "steps_per_unit" argument is, I want to stress, based on the calculators around that compute the number of teeth on GT-2 pulleys.

Changing that value to something else means we then have to provide our own "steps_per_unit" calculator based on the number of teeth on a pulley. While feasible, I don't think we want to modify the system so drastically users can't simply take their steps_per_mm from an old Marlin firmware they had on their chassis...

@eliasbakken
Copy link
Contributor

eliasbakken commented Jan 23, 2019 via email

@zaped212
Copy link
Contributor

What do you guys think about an intermediate step?

Instead of changing the whole config at once and requiring anyone who updates past it to redo their entire config we honor their old config values.

I suggest that we create new config names:
offset_x -> existing name means SI units aka offset_x_m
offset_x_mm -> means units in mm

Then we update the logic that reads the configuration to detect offset_x vs offset_x_mm and handle the conversion internally.
There might be some work around converting the speed values automatically might not just be a simple * 1000 multiple. but might end up pretty clean plus would give us functionality to handle different units.

Then as new values are written out we could standardize on a single format.

I think eitherway we would want to change the config name ( apply units ) else we will have confusion about what units that value is supposed to be.

@Wackerbarth
Copy link
Contributor Author

Yes, a variation of this would be my preferred approach.
I introduced a configuration version header in each config file so that Redeem can quickly detect "obsolete" configurations and generate an error message or automatically run a migration tool to convert to the next generation.

The advantage in doing the conversion in a program external to Redeem is that the running code is not burdened by the conversion details and it can more readily check for invalid entries. It also leaves the option for the migration tool to "fail" and request manual correction if there is a case that it does not know how to handle.

And I also think that it is a good idea to include the units in the name of each setting. That way, in the future, the values can remain simply numbers but the units are quite apparent to anyone reading the configuration as text.

@RaveGun
Copy link

RaveGun commented Jan 23, 2019

How is the whole configuration process running?

Are the configuration files read in the order described in the manual: default, printer and then local and the values are overwritten?

Maybe we could have some sort of precompile step that is generating an active configuration during the redeem startup, like a translator

This way we can have the intermediate step but also change redeem's configuration parser internal behaviour. This also removes the runtime overload for the unit conversions.

@zaped212
Copy link
Contributor

@RaveGun yeah I was wondering about this as well.
Doesnt seem like there should be a need to re-read the configuration file, but instead cache the current working configuration and then when changes are made ( m500 ) and differences / modified lines could be spit out to the local config file.

Doing that would also help with data consistency as the main data source would then be the cached copy.

Acheiving this logic would just be modifying the config read and write functions to work out of the cache instead.

@Wackerbarth
Copy link
Contributor Author

That is already the basic case. The files are identified and read at startup and thereafter the stored values are used. The only difficulty in doing all of it in the existing Redeem structure has to do with the limits on the present parser with respect to valid expressions and other error checking. Since we need to have the core part of the Redeem controller running, handling these conversions adds a layer of complexity in terms of error handling and also efficiency.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants