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

Rotational dynamics units #227

Merged
merged 3 commits into from
May 13, 2017

Conversation

PhilipAxelrod
Copy link
Contributor

Create units related to rotational dynamics such as Torque, MomentOfInertia, and AngularAcceleration.

Copy link
Collaborator

@cquiroz cquiroz left a 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 ⇒
Copy link
Collaborator

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

Copy link
Contributor Author

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
Copy link
Collaborator

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

Copy link
Contributor Author

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]) {
Copy link
Collaborator

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

Copy link
Contributor Author

@PhilipAxelrod PhilipAxelrod May 1, 2017

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.

Copy link
Contributor

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 + "²"
Copy link
Collaborator

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?

Copy link
Contributor Author

@PhilipAxelrod PhilipAxelrod May 1, 2017

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²"
Copy link
Collaborator

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?

Copy link
Contributor Author

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²"
Copy link
Collaborator

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)
Copy link
Collaborator

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?

Copy link
Contributor Author

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.

Copy link
Collaborator

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.

Copy link
Contributor Author

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

Copy link
Contributor Author

@PhilipAxelrod PhilipAxelrod May 1, 2017

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

Copy link
Contributor Author

@PhilipAxelrod PhilipAxelrod May 1, 2017

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)
}


Copy link
Collaborator

Choose a reason for hiding this comment

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

2 lines?

Copy link
Contributor Author

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 = {
Copy link
Collaborator

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
Copy link
Collaborator

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?

Copy link
Contributor Author

@PhilipAxelrod PhilipAxelrod May 1, 2017

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.

@PhilipAxelrod PhilipAxelrod force-pushed the rotational-dynamics-units branch 3 times, most recently from 373ae33 to 7c49aad Compare May 5, 2017 23:52
val conversionFactor = Degrees.conversionFactor
}

object GradiansPerSecondSquared extends AngularAccelerationUnit {
object GradsPerSecondSquared extends AngularAccelerationUnit {
Copy link
Collaborator

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

Copy link
Contributor Author

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?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@@ -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 ⇒
Copy link
Collaborator

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

Copy link
Contributor Author

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.

@cquiroz
Copy link
Collaborator

cquiroz commented May 7, 2017

I'm ok with this PR as it is now but will wait for others to chime in, @derekmorr?

…uch as Torque, MomentOfInertia, and AngularAcceleration. In addition, add multiply methods to Angle and AngularVelocity
…sion from Energy to Torque, and simplify code
@cquiroz cquiroz mentioned this pull request May 8, 2017
@cquiroz
Copy link
Collaborator

cquiroz commented May 12, 2017

Can we proceed with this PR? It seems fine to me

@derekmorr
Copy link
Collaborator

My only objection was renaming GradsPerSecond to GradiansPerSecond since it changes existing API.

@cquiroz
Copy link
Collaborator

cquiroz commented May 12, 2017

I see, I proposed that to make it consistent with Angle but right it would break the API. Could we deprecate the existing and add Gradians?

@derekmorr
Copy link
Collaborator

Sure that would work. Do you want to add that to this PR or make a new one for it ?

@cquiroz
Copy link
Collaborator

cquiroz commented May 12, 2017

@paxelord Could you implement the change suggested by @derekmorr and then we can merge

@PhilipAxelrod
Copy link
Contributor Author

PhilipAxelrod commented May 13, 2017

@cquiroz @derekmorr I have added the GradsPerSecond back, in addition to deprecation warnings. Thanks a ton for helping me make this pr open source worthy!

Copy link
Collaborator

@cquiroz cquiroz left a 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

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.

4 participants