<< return to Pixycam.com

Code for object following robot

Hi,
Couple of questions.

Is the code you used in the great marketing video for the purple dinosaur (coloured object) following robot open source, or going to be made so in the near future?

Will you be making any Pixy specific tutorials available for beginners looking to interface this cam with either Arduino or R-Pi?

Roughly whats the maximum range / distance Pixy is able to track or follow colours, given a good object hue and good lighting?

Many thanks, cant wait for international shipping!!

Odin

Hi,

The code from that video is much older than what is released now, but we’ll look in to fixing it up so we can post it as an example. Its pretty similar to how the pan-tilt demo works, except that the output drives the robots wheels instead of servo motors, so you can look at that demo for help too.

Beginner tutorials are on the to-do list, so we’ll try to get to those once we’re done shipping Pixys and finished the 1.0 release.

As for a max range, it all depends on the size of your object and the resolution you’re using (as well as hue and lighting, as you mentioned). I believe we are currently restricting objects to being 3x3 pixels in size in order for it to be ‘detected’. So you’ll have to figure out at what distance and resolution your object will be ~3x3 pixels in size.

Scott

Thats great, thanks. Another couple of questions please.

Can Pixy run both the tilt/pan program and output these values to Arduino at the same time?

What levels of P&D gain did you find best to track a fast moving object? I noticed the table tennis video shows quite impressive response, my object will be at similar speed though maybe at slightly greater distances. Accurate chasing / tracking is quite important for my application.

Thanks again

I will be reading this post too because Im a beguinner as well. Im using a small arduino car with a dual motor driver just to chase a ball.
thanks

Hi Zed,

Here are the default values for P&D gains:

Pan axis proportional gain: 500
Pan axis derivative gain: 800
Tilt axis proportional gain: 700
Tilt axis derivative gain: 900

I can’t tell you what works best since I don’t know enough about P&D gains, but I’m sure these are the defaults for a reason. I’ll see if I can get someone else to help answer that.

Also, Pixy is capable of running the pan/tilt demo and outputting the values to SPI/serial.

Thanks.

Scott

Hi,
We too are looking forward to the release of the following code.
You did say it could do EVERYTHING in the video’s, out of the box, right?
As-is is fine since our robot is undoubtedly different from yours.

Thanks

We could post the code, but it would only apply to the particular parts that we cobbled together (wouldn’t make a good/useful tutorial)
Like Scott says, the PD loop in the pan/tilt demo has the exact same structure as the chase demo. If that doesn’t make sense,I’m happy to explain more…

This brings me to a related topic — what we really need is good differential-drive base that we can suggest people buy and use in a tutorial. This base needs to be reasonably zippy (no RC-servo motors --they’re too slow!) and not too expensive. On the small side is good too. Let us know if there are any suggestions out there. If you have a base you can sell us (or others) in quantity, that works too.

I know something is out there, I just haven’t come across something I like yet…

For example, all of these are either slow, or too expensive—
http://www.amazon.com/s/ref=nb_sb_noss_2?url=search-alias%3Daps&field-keywords=robot%20base

but maybe we should settle on something or come up with something ourselves. :slight_smile:

Regarding a good diff-drive base, I would certainly be a +1 if you did something yourselves.

2 reasons, firstly if I can buy a complete solution from one source that is well specced, simple to use and competitively priced (<$50) then its a no-brainer, every time.

Second, there is almost certainly a current gap in the market for something that ticks all the boxes listed above, if you could do it using decent quality stepper motors (brushless) and still return a good speed it would be a killer robotics solution. - From what I have seen on the stepper side however this is maybe where platforms like Arduino struggle a little. Dedicated motor encoders and an interface similar to what you have with PIXY would possibly the answer (for me at least!).

On with the project!!!

Rich LeGrand wrote:

We could post the code, but it would only apply to the particular parts that we cobbled together (wouldn’t make a good/useful tutorial)
Like Scott says, the PD loop in the pan/tilt demo has the exact same structure as the chase demo. If that doesn’t make sense,I’m happy to explain more…

Yep that would be great if you could please, I am fairly inexperienced in C+ programming.

Regards

Hi Zed,
Here’s the code. It uses a proportional-dervative loop in rotation and translation of the robot and then maps these “virtual” motor axes to real (physical) left and right wheels.

It’s sort of inviting trouble just posting code like this, but here goes… (it won’t compile because not everything is here, just the important stuff)


#define LEFT_AXIS       0
#define RIGHT_AXIS      1
#define Y_TRACK         130 // sets how close the robot gets to the object before stopping

#define X_CENTER        (320/2)
#define MOTOR_MAX       500
#define MOTOR_MIN       -500

class MotorLoop
{
public:
MotorLoop(uint32_t pgain, uint32_t dgain);

int32_t update(int32_t error);

private:

int32_t m_prevError;
int32_t m_pgain;
int32_t m_dgain;
};

MotorLoop::MotorLoop(uint32_t pgain, uint32_t dgain)
{
m_pgain = pgain;
m_dgain = dgain;
m_prevError = 0x80000000; // to indicate that it's never been set
}

// control loop update!
int32_t MotorLoop::update(int32_t error)
{
int32_t vel;

if (m_prevError!=0x80000000)
{
vel = (error*m_pgain + (error - m_prevError)*m_dgain)/1000; // calc proportional-derivative
// saturation
if (vel>MOTOR_MAX)
vel = MOTOR_MAX;
else if (vel<MOTOR_MIN)
vel = MOTOR_MIN;
}
m_prevError = error;

return vel;
}



// Map axes!  go from translational/rotational to left/right wheel space
void axisMap(int32_t in[], int32_t out[])
{
  out[0] = (in[0] - in[1])/2;
out[1] = (in[0] + in[1])/2;
}

// calculate left and right wheel commands based on x, y value of blob
// just call this over and over again and robot will chase ball
void combine(uint32_t x, uint32_t y)
{
int32_t xError, yError, axesIn[2], axesOut[2];

xError = X_CENTER-x;
yError = Y_TRACK-y;

axesIn[0] = g_transLoop.update(yError);
axesIn[1] = g_rotLoop.update(xError);

axisMap(axesIn, axesOut);

setMotorVoltage(LEFT_AXIS, axesOut[0]);
setMotorVoltage(RIGHT_AXIS, axesOut[1]);
}

static MotorLoop g_transLoop(500, 800);
static MotorLoop g_rotLoop(700, 900);

Thats great, thank you very much. Just out of interest, what motors did you use?

I used Lego motors from the RCX 1.0 kit (old!) and some custom drive electronics.

Hi,

I have a question about #define LEFT_AXIS 0 and #define RIGHT_AXIS 1 ,what are the 0 and 1 corresponds to?,sorry for my question.
Thank You.

armand