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

RSDK-6632 - Typescript SDK throws if MotionConfiguration.obstacleDetectorsList is not specified #249

Merged
merged 8 commits into from
Mar 1, 2024

Conversation

nfranczak
Copy link
Member

Steps to reproduce :

Typescript SDK encodeMotionConfiguration throws an exception if MotionConfiguration.obstacleDetectorsList is not specified

Expected behavior :

Typescript SDK allows all MotionConfiguration attributes to be optional

@nfranczak
Copy link
Member Author

relates to viamrobotics/rdk#3574

result.setPlanDeviationM(obj.planDeviationM);
result.setLinearMPerSec(obj.linearMPerSec);
result.setAngularDegsPerSec(obj.angularDegsPerSec);
result.setPositionPollingFrequencyHz(obj.positionPollingFrequencyHz ?? 1);
Copy link
Member

@micheal-parks micheal-parks Feb 27, 2024

Choose a reason for hiding this comment

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

Are these necessary to coalesce? In other words, will this break somewhere if we do not send default values? My concern is that default values now potentially exist - and would need to be maintained - in multiple places (SDK and robot).

Copy link
Member Author

Choose a reason for hiding this comment

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

Are these necessary to coalesce? In other words, will this break somewhere if we do not send default values?... My concern is that default values now potentially exist - and would need to be maintained - in multiple places (SDK and robot).

Good catch! I will change this to be:

  if (obj.angularDegsPerSec) {
    result.setAngularDegsPerSec(obj.angularDegsPerSec);
  }

result.setPlanDeviationM(obj.planDeviationM);
result.setLinearMPerSec(obj.linearMPerSec);
result.setAngularDegsPerSec(obj.angularDegsPerSec);
if (obj.positionPollingFrequencyHz) {
Copy link
Member

Choose a reason for hiding this comment

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

It would be safer for these checks to do:

if ('positionPollingFrequencyHz' in obj) {
  result.setPositionPollingFrequencyHz(obj.positionPollingFrequencyHz)
}

The current check will evaluate to false if any of these props are zero, and therefore won't be set, which will cause unexpected behavior.

Copy link
Member Author

Choose a reason for hiding this comment

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

with this, when linting, I run into:

src/services/motion/types.ts(88,42): error TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'.
  Type 'undefined' is not assignable to type 'number'.

I will change the conditionals to be:

if (obj.positionPollingFrequencyHz !== undefined) {
    result.setPositionPollingFrequencyHz(obj.positionPollingFrequencyHz);
}

this way even if any of the props are zero or false they are set.

Copy link
Member

Choose a reason for hiding this comment

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

That works!

@@ -71,8 +71,9 @@ export const encodeMotionConfiguration = (
): pb.MotionConfiguration => {
const result = new pb.MotionConfiguration();

const { obstacleDetectorsList = [] } = obj;
Copy link
Member

Choose a reason for hiding this comment

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

How does this behave:

  1. if obj is undefined?
  2. if obstacleDetectorsList is not a member of obj?

Copy link
Member

@micheal-parks micheal-parks Feb 28, 2024

Choose a reason for hiding this comment

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

  1. The parameter type for obj for this function states that it will never be undefined. If that's not the case, it should be an optional param, and the param should recieve a default value:
export const encodeMotionConfiguration = (
  obj?: MotionConfiguration = {}
): pb.MotionConfiguration =>
  1. If it's not a member of this object, it will be assigned a default value of [].

Copy link
Member Author

@nfranczak nfranczak Feb 28, 2024

Choose a reason for hiding this comment

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

if obj is undefined?

The parameter type for obj for this function states that it will never be undefined. If that's not the case, it should be an optional param, and the param should recieve a default value:

Within typescript-sdk/src/services/motion/client.ts for moveOnGlobe and moveOnMap we do

    if (motionConfig) {
      request.setMotionConfiguration(encodeMotionConfiguration(motionConfig));
    }

So I think it is safe to assume that obj will not be undefined entirely.

Copy link
Member

Choose a reason for hiding this comment

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

In this case I'd actually recommend making this an optional param like I've done above. If all fields are optional then there's no reason the user should have to pass an empty object into this function.

@nicksanford
Copy link
Member

@nfranczak Tests are not passing

@@ -67,12 +67,13 @@ export const encodeConstraints = (obj: Constraints): pb.Constraints => {
};

export const encodeMotionConfiguration = (
obj: MotionConfiguration
obj: MotionConfiguration = {}
Copy link
Member Author

Choose a reason for hiding this comment

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

@micheal-parks since I added this, do you think I should remove

    if (motionConfig) {
      request.setMotionConfiguration(encodeMotionConfiguration(motionConfig));
    }

from src/services/motion/client.ts?

Copy link
Member

@micheal-parks micheal-parks Feb 29, 2024

Choose a reason for hiding this comment

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

I think it still makes sense to not call this function if no config is provided, unless something will break if it's not called

Copy link
Member

@nicksanford nicksanford left a comment

Choose a reason for hiding this comment

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

Please confirm this change works with the RDK RC card post-merge (or ideally pre-merge if you can).

@nfranczak
Copy link
Member Author

Please confirm this change works with the RDK RC card post-merge (or ideally pre-merge if you can).

@nicksanford @micheal-parks Would you know how to test this change pre-merge - is that possible?

@micheal-parks
Copy link
Member

Pre-merge might be difficult with our current setup, I think post-merge is fine for now. All you'll have to do is:

  1. bump the SDK version in this repo's package.json. That'll trigger our CI pipeline to ship a new version to NPM
  2. install the new version in the RDK, use this method, and run npm run check. Nick S might be able to assist since he already started work here.

Copy link
Member

@micheal-parks micheal-parks left a comment

Choose a reason for hiding this comment

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

Thanks for addressing my comments, good stuff!

@nfranczak nfranczak merged commit 3274e0d into viamrobotics:main Mar 1, 2024
3 checks passed
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.

None yet

4 participants