API function requests

So playing around with some python code and trying to get some basics down I came across a few missing functions that are either really necessary or very good to have. So thought we can collect function requests here so the Sphero team knows what we are looking for.

So for me necessary would be:
shutdown - send the RVR into deep sleep meaning power it down. This would need to have a parameter to wait some seconds so when you have a Raspberry connected you can gracefully shut that down before power goes out. (I saw a discussion in another thread that there seems to be a message you can send already that can do this, but no clue how send this as raw data, so maybe someone has an idea?)

drive by distance - let the RVR drive a certain distance. Probably with a parameter in mm or cm? Don’t think that a precision down to mm is realistic so down to cm would be great.

drive to x,y - let the RVR drive to a certain point in its own coordinate system. Tried to implement this by getting heading from the line of the current location to a target point, but ran into other issues here. One of the problem here is also that setting the heading only works with integers, so it is quite low precision here. When driving a few cm a heading in integer degrees does not matter much, but if you are half a degree off and drive several meters being half a degree of can miss the wanted target location by a lot. Can be circumvented by checking heading along the way and correcting it when it is off. But that is a lot of data going over the serial line so it makes more sense to have this build in the RVR.

set turn speed - it seems when changing the heading the RVR always does that full speed. So quite often the heading is off a bit. Or when turning on the spot the RVR actually drives a bit into some random direction while turning. For my project I really need it to be able to turn on the spot and not change location while doing so.

enable/disable bluetooth - from another thread we know that bluetooth is always active and shares the serial line. When using a Raspberry for example think most will use the bluetooth of the Raspberry for communication so it makes no sense keeping the bluetooth of the RVR active.

Functions that are nice to have would be:
drive curve - essentially you can slice down a curve into small straight segments and that would work, but some way to really drive a curve/circle would make it much much easier and nicer.

set heading to point goes hand in hand with the drive to x,y. So target coordinates as a parameter and the RVR turns to face that point.

Hope some of these can be considered. Some are a blocker for me at the moment. So spending time to build everything else around it at the moment, but to complete what I want to do with the RVR I probably reach a wall soon till the next firmware update. If anyone else has more suggestions let us collect all here :wink:

1 Like

Hey @RuyLightworks!

Putting requests in a thread is a great idea :slight_smile:

I’ll need to reach out to the team for some of them, but many are in existence/in progress!

As you noted, there is a shutdown command in the API already. The device ID is 0x13 and the Command ID is 0x00. It also has an optional input for the number of seconds you would like to wait before the shutdown occurs. You can read more about the API and how packets are constructed in the docs on the SDK site :slight_smile:

Drive by distance, drive to xy and drive curve are all in progress now and are expected to be released in Q1 2020, barring any changes in priorities per requests from super awesome users like yourself :wink:

I have seen comments about the turn speed being a bit abrupt, especially at lower speeds. With our orb-shaped robots, this was less of an issue, but my understanding is that we are exploring making the turn speed proportional to the overall speed (I will need to double check on that, though).

I don’t see anything in even our internal API about disabling Bluetooth, so I’ll have to bring this one up with the engineers :slight_smile:

I like the idea of “set heading to a point” I think that depending on the exact implementation, you can either accomplish this now OR it will be possible to do with the (above) items we are hoping to release in early 2020.

Thanks again and I’ll let you know as I get any new information!

Kelsey

1 Like

Thanks for the heads up. Glad to hear that most is already being worked on.

Do you have a code example on how to send that raw bytes using python? Didn’t dive down to the base level of communication (and was hoping I don’t have to) so not 100% sure on how to code this. Think I saw some of this in the python repository but looked like it was encapsuled within the controller class so guess would need to open the channel communication by foot there too.

About the turn speed if it becomes proportional to the drive speed then turning on the spot needs to be addressed differently. Or maybe have a function to set general speed and have drive commands without a speed parameter that uses this speed setting. Turning at the moment really lets the RVR dance all over the place. Just a couple of 180° turns and you never know where it ends up :wink:

The heading to a point could be implemented right now, not that difficult of a calculation there. But getting the current position of the RVR is still something I am trying to figure out. See comment on the other thread about programming questions. The values you get from the locator module look extremely high to be coordinates based on a distance. If there is a way to get the location based on distance then this would be an easy implementation of the heading function:

async def get_heading(source, target):
    """
    Calculates the heading between two points.
    Formula used:
        θ = atan2(sin(Δy).cos(x2), cos(x1).sin(x2) − sin(x1).cos(x2).cos(Δy))
    :param source: The tuple representing x, y of source point
    :param target: The tuple representing x, y of target point
    :return: The heading in degrees as float
    """
    if (type(source) != tuple) or (type(target) != tuple):
        raise TypeError("Only tuples are supported as arguments")

    lat1 = math.radians(source[0])
    lat2 = math.radians(target[0])

    diff_long = math.radians(target[1] - source[1])

    x = math.sin(diff_long) * math.cos(lat2)
    y = math.cos(lat1) * math.sin(lat2) - (math.sin(lat1) * math.cos(lat2) * math.cos(diff_long))

    math_bearing = math.atan2(x, y)

    # The normalize the heading from -180° to + 180° > 360°
    math_bearing = math.degrees(math_bearing)
    degree_bearing = (math_bearing + 360) % 360

    return degree_bearing
1 Like

Just tested the power off (0x13, 0x00). It takes a unsigned 8 bit int value. Raw bytes are 8D 1A 1 13 0 88 5 44 D8 for a 5 second delay.

Since I’m running from my PC it isn’t dependent on the RVR power. A did sleep notify notification is sent just before the power actually dies. Not much use if you’re controllers power also dies. Some may have separate battery power so that could be useful.

I started out sending raw byte streams using a serial terminal, CuteCom. You’ll need to calculate the sum byte in code or by hand and copy the resulting output stream to the terminal.

1 Like

That’s strange that the shutdown command is not documented but the sleep and wake are. Just put into my code and works nicely. I kind of was just looking for that since it’s in the blocks code.

It also looks like the locate(x,y) code measures distance in cm from the starting position. Ran some block code to test this out and the Y axis is forward and backwards while X is in the left to right direction. So if RVR is maintaining is direction the X value should be zero. IE there is no sideways movement.

Mike

1 Like