-
Notifications
You must be signed in to change notification settings - Fork 122
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
Rotational dynamics units #227
Conversation
f92dd88
to
a9729ce
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for your contribution. It seems this fills an important missing piece on squants
I added some comments inline
|
||
abstract class StrictlyPositiveQuantity[A <: StrictlyPositiveQuantity[A]](value: Double) extends Quantity[A] {self: A ⇒ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is interesting though I'd strongly prefer have a constructor returning an Option[StrictlyPositiveQuantity[A]]
than throwing an exception here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cquiroz this feature leads to many different complications that are outside of the scope of this PR, so I have decided to remove it. I have addressed all your comments, and I think this PR is now ready to be merged! Thank you!
/** | ||
* | ||
* @author paxelord | ||
* @since 0.6 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are at version 1.2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will make sure to change this
lazy val kilogramMetersSquared = KilogramsMetersSquared(1) | ||
lazy val poundSquareFeet = PoundsSquareFeet(1) | ||
|
||
implicit class MassConversions[A](n: A)(implicit num: Numeric[A]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be made a value class? maybe not with the implicit there
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand, can you please clarify?
If it helps, I accidentally misnamed what should have been MomentOfInertiaConversions
to MassConversions
by mistake. I don't even know how that happened.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just chiming in, @paxelord and I are on the same robotics team, where we're using Squants. I think this can still be made into a value class, if the implicit is moved to the methods. So MassConversions
(or MomentofInertiaConversions
I guess) would only take a val n
, and the kilogramMetersSquared
and poundSquareFeet
would take the implicit Numeric
.
} | ||
|
||
object KilogramsMetersSquared extends MomentOfInertiaUnit with PrimaryUnit with SiBaseUnit { | ||
val symbol = Kilograms.symbol + "‧" + Meters.symbol + "²" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we using exponentials in unicode like this in other places?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Acceleration and Area, unicode exponentials are used.
} | ||
|
||
object RadiansPerSecondSquared extends AngularAccelerationUnit with PrimaryUnit with SiUnit{ | ||
override val symbol: String = "rad/s²" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't you use Radians.symbol
here to be consistent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad, I'll change that!
} | ||
|
||
object DegreesPerSecondSquared extends AngularAccelerationUnit { | ||
val symbol = "°/s²" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
} | ||
|
||
object MomentOfInertia extends Dimension[MomentOfInertia] { | ||
private[mass] def apply[A](n: A, unit: MomentOfInertiaUnit)(implicit num: Numeric[A]) = new MomentOfInertia(num.toDouble(n), unit) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could the constructors here return an Option
to account for negative values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not 100% sure that's a good idea. People might be confused why they are getting a None.get
Exception, whereas as throwing an IlleagalArgumentException would be more descriptive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throwing exceptions isn't very functional. If Option
isn't suitable, we can look at Either
which has a place to place an error data structure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will try experimenting with Option
and Either
, and try to figure out what is most natural
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a side note, I am starting to second guess whether this class should even exist. Maybe Squants should only provide compile time safety of units, and not tell people how to represent quantities, even if they are doing unusual things like having negative Mass
or MomentOfInertia
.
This might hinder people trying to explain legitimate scientific phenomena: https://en.wikipedia.org/wiki/Negative_mass
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One compromise would be to have the strictly positive feature optional, enabled by default. Someone who needs to use negative mass would have to explicitly disable the strictly positive feature. I'm not completely sure how that would work though.
override protected[squants] def time: Time = Seconds(1) | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 lines?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will make sure to change this to just 1 line.
* @param radius the distance from the center of rotation | ||
* @return linear velocity with given angular velocity and radius | ||
*/ | ||
def onRadius(radius: Length): Velocity = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need the {
parentheses here
} | ||
|
||
object NewtonMeters extends TorqueUnit with PrimaryUnit with SiBaseUnit { | ||
val symbol = Newtons.symbol + "‧" + Meters.symbol |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a times
symbol? Are we using the same on other units?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is meant to be the times symbol. I looked though squants, and I think this is the first time we have a times symbol in a unit. It might be clearer to replace the current bullet ‧
with a splat *
In a future PR, it might be useful to have have a Integral[Unit]
and Derivative[Unit]
, similar to TimeDerivative
and TimeIntegral
, to allow for easy extendability of units. For example, Energy
would extend Integral[Force]
with Integral[Length]
. Or even better, something along the lines of Integral[Integrand, RespectTo]
But that's for a future PR.
373ae33
to
7c49aad
Compare
val conversionFactor = Degrees.conversionFactor | ||
} | ||
|
||
object GradiansPerSecondSquared extends AngularAccelerationUnit { | ||
object GradsPerSecondSquared extends AngularAccelerationUnit { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the change to Grads
? Gradians
seems clearer at the costs of just a few letters. In Spanish Grads
can be easily confused by Degrees
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made it Grads
instead of Gradians
because that was the convention used in AngularVelocity
. However, I agree with you about Gradians
being clearer, and I will change it. Do you also want to change that in AngularVelocity
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think it should be consistent with the units on Angle
@@ -308,8 +308,3 @@ abstract class Quantity[A <: Quantity[A]] extends Serializable with Ordered[A] { | |||
def map(f: Double ⇒ Double): A = unit(f(value)) | |||
} | |||
|
|||
abstract class StrictlyPositiveQuantity[A <: StrictlyPositiveQuantity[A]](value: Double) extends Quantity[A] {self: A ⇒ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry about this. I think this can be made to work just making the constructors return Option
or Either
or even Try
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that we run into complications such as these: Take the scenario KilogramsMetersSquared(1) - KilogramsMetersSquared(2) + KilogramsMetersSquared(2)
After the first subtraction, we get a negative moment, resulting in None
. The addition afterwards would add a None
with a KilogramsMetersSquared(2)
, getting None
However, mathematically, this should be evaluated to the equivalent of Some(KilogramsMetersSquared(1))
. Implementing this kind of feature is certainly possible, but scenarios such as these make it complicated and outside the scope of this pr.
I'm ok with this PR as it is now but will wait for others to chime in, @derekmorr? |
7c49aad
to
ffb8ee7
Compare
…uch as Torque, MomentOfInertia, and AngularAcceleration. In addition, add multiply methods to Angle and AngularVelocity
…sion from Energy to Torque, and simplify code
ffb8ee7
to
9f76785
Compare
Can we proceed with this PR? It seems fine to me |
My only objection was renaming |
I see, I proposed that to make it consistent with |
Sure that would work. Do you want to add that to this PR or make a new one for it ? |
@paxelord Could you implement the change suggested by @derekmorr and then we can merge |
9f76785
to
4f277d3
Compare
@cquiroz @derekmorr I have added the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot @paxelord for your contribution
Create units related to rotational dynamics such as Torque, MomentOfInertia, and AngularAcceleration.