September 8, 2016

The Circle Tutorial

I can see you!

In this section we will consider orientation and determining when we are aimed at objects. Start a new program and call it “Tank”. In this section we will program the satellite to rotate until it is facing the other satellite and then drive over to it. Unlike the previous example we will use the very simple logic of continuously aiming at the other SPHERE and if we’re facing the other satellite we’ll drive to it.

The key new element here is determining our angle to the other satellite. For this we will use the Inner Dot Product. Again there is an API function for this mathVecInner() which takes two vectors and of course the number of elements in each vector as parameters. The function returns cos(θ)|v1||v2| which is the cosine of the angle between the two vectors times the magnitude of v1 times the magnitude of v2. So if we create a special case by using normalized (unit) vectors, the result is simply cos(θ) where θ is the angle between the two vectors. As this angle approaches 0 degrees, the cosine approaches 1. It follows then that we simply need to check if the dot product is close enough to 1 to consider us facing the other satellite. Anything above .985 should give us roughly a 20 degree cone. Why?

The second new element in this section is rotating our satellite.  For this exercise we’ll use setAttitudeTarget(), the trick is that we have to know the attitude target vector.

Any thoughts?

It’s not too tough.

If we know the vector that represents the trip to the target and normalize it we’ll have the direction we want to go. What was the vector from here to there again?

As we discussed earlier, the trip from here to there is there-here and that is the direction in which we want to point. Let’s get started by doing the rotation. First we need to get the state of both satellites. Then we can calculate the direction to the other satellite and normalize it. Finally we will use setAttitudeTarget. The code looks like this:

void init(){
}
 
void loop(){
    float MyState[12];
    float OtherState[12];
 
    api.getMyZRState(MyState);
    api.getOtherZRState(OtherState);
 
    float dir[3];
    mathVecSubtract(dir,OtherState,MyState,3);
    mathVecNormalize(dir,3);
     
    api.setAttitudeTarget(dir);
}

This should rotate us to the other satellite, try it. Then we need to perform the calculations to determine the dot product of the our orientation and the dir vector we already have. Once we have dot product we can decide what to do. Like this:

void loop(){
    float MyState[12];
    float OtherState[12];
 
    api.getMyZRState(MyState);
    api.getOtherZRState(OtherState);
 
    float dir[3];
    mathVecSubtract(dir,OtherState,MyState,3);
    mathVecNormalize(dir,3);
     
    api.setAttitudeTarget(dir);
 
    float dotProd = mathVecInner(dir,&MyState[6],3);
    if(dotProd>.985)
    {
        api.setPositionTarget(OtherState);
    }
}

Cool, that should do it.

Did you catch what happened at the end?

The satellite spinning!

Do you know why?