source: rtos_arduino/trunk/examples/PIXY_Zumo/r2ca_app.cpp@ 260

Last change on this file since 260 was 260, checked in by ertl-honda, 8 years ago

マクロ名を更新.
実行モデルを変更.

File size: 6.2 KB
Line 
1#include "r2ca.h"
2#include <Wire.h>
3#include <ZumoShield.h>
4
5#include <SPI.h>
6#include <Pixy.h>
7
8//==========================================================================
9//
10// Pixy Pet Robot
11//
12// Adafruit invests time and resources providing this open source code,
13// please support Adafruit and open-source hardware by purchasing
14// products from Adafruit!
15//
16// Written by: Bill Earl for Adafruit Industries
17//
18//==========================================================================
19// begin license header
20//
21// All Pixy Pet source code is provided under the terms of the
22// GNU General Public License v2 (http://www.gnu.org/licenses/gpl-2.0.html).
23//
24// end license header
25//
26//==========================================================================
27//
28// Portions of this code are derived from the Pixy CMUcam5 pantilt example code.
29//
30//==========================================================================
31
32#define X_CENTER 160L
33#define Y_CENTER 100L
34#define RCS_MIN_POS 0L
35#define RCS_MAX_POS 1000L
36#define RCS_CENTER_POS ((RCS_MAX_POS-RCS_MIN_POS)/2)
37
38//---------------------------------------
39// Servo Loop Class
40// A Proportional/Derivative feedback
41// loop for pan/tilt servo tracking of
42// blocks.
43// (Based on Pixy CMUcam5 example code)
44//---------------------------------------
45class ServoLoop
46{
47public:
48 ServoLoop(int32_t proportionalGain, int32_t derivativeGain);
49
50 void update(int32_t error);
51
52 int32_t m_pos;
53 int32_t m_prevError;
54 int32_t m_proportionalGain;
55 int32_t m_derivativeGain;
56};
57
58// ServoLoop Constructor
59ServoLoop::ServoLoop(int32_t proportionalGain, int32_t derivativeGain)
60{
61 m_pos = RCS_CENTER_POS;
62 m_proportionalGain = proportionalGain;
63 m_derivativeGain = derivativeGain;
64 m_prevError = 0x80000000L;
65}
66
67// ServoLoop Update
68// Calculates new output based on the measured
69// error and the current state.
70void ServoLoop::update(int32_t error)
71{
72 long int velocity;
73 char buf[32];
74 if (m_prevError!=0x80000000)
75 {
76 velocity = (error*m_proportionalGain + (error - m_prevError)*m_derivativeGain)>>10;
77
78 m_pos += velocity;
79 if (m_pos>RCS_MAX_POS)
80 {
81 m_pos = RCS_MAX_POS;
82 }
83 else if (m_pos<RCS_MIN_POS)
84 {
85 m_pos = RCS_MIN_POS;
86 }
87 }
88 m_prevError = error;
89}
90// End Servo Loop Class
91//---------------------------------------
92
93Pixy pixy; // Declare the camera object
94
95ServoLoop panLoop(200, 200); // Servo loop for pan
96ServoLoop tiltLoop(150, 200); // Servo loop for tilt
97
98void ScanForBlocks();
99void FollowBlock(int trackedBlock);
100int TrackBlock(int blockCount);
101
102//---------------------------------------
103// Setup - runs once at startup
104//---------------------------------------
105void setup()
106{
107 ZumoInit();
108 buzzer.playOn();
109 Serial.begin(115200);
110 Serial.print("Starting...\n");
111 pixy.init();
112
113 button.waitForPress();
114 buzzer.playStart();
115}
116
117uint32_t lastBlockTime = 0;
118
119//---------------------------------------
120// Main loop - runs continuously after setup
121//---------------------------------------
122void loop()
123{
124 uint16_t blocks;
125 blocks = pixy.getBlocks();
126
127 // If we have blocks in sight, track and follow them
128 if (blocks)
129 {
130 int trackedBlock = TrackBlock(blocks);
131 FollowBlock(trackedBlock);
132 lastBlockTime = millis();
133 }
134 else if (millis() - lastBlockTime > 100)
135 {
136 motors.setLeftSpeed(0);
137 motors.setRightSpeed(0);
138 ScanForBlocks();
139 }
140}
141
142int oldX, oldY, oldSignature;
143
144//---------------------------------------
145// Track blocks via the Pixy pan/tilt mech
146// (based in part on Pixy CMUcam5 pantilt example)
147//---------------------------------------
148int TrackBlock(int blockCount)
149{
150 int trackedBlock = 0;
151 long maxSize = 0;
152
153 Serial.print("blocks =");
154 Serial.println(blockCount);
155
156 for (int i = 0; i < blockCount; i++)
157 {
158 if ((oldSignature == 0) || (pixy.blocks[i].signature == oldSignature))
159 {
160 long newSize = pixy.blocks[i].height * pixy.blocks[i].width;
161 if (newSize > maxSize)
162 {
163 trackedBlock = i;
164 maxSize = newSize;
165 }
166 }
167 }
168
169 int32_t panError = X_CENTER - pixy.blocks[trackedBlock].x;
170 int32_t tiltError = pixy.blocks[trackedBlock].y - Y_CENTER;
171
172 panLoop.update(panError);
173 tiltLoop.update(tiltError);
174
175 pixy.setServos(panLoop.m_pos, tiltLoop.m_pos);
176
177 oldX = pixy.blocks[trackedBlock].x;
178 oldY = pixy.blocks[trackedBlock].y;
179 oldSignature = pixy.blocks[trackedBlock].signature;
180 return trackedBlock;
181}
182
183//---------------------------------------
184// Follow blocks via the Zumo robot drive
185//
186// This code makes the robot base turn
187// and move to follow the pan/tilt tracking
188// of the head.
189//---------------------------------------
190int32_t size = 400;
191void FollowBlock(int trackedBlock)
192{
193 int32_t followError = RCS_CENTER_POS - panLoop.m_pos; // How far off-center are we looking now?
194
195 // Size is the area of the object.
196 // We keep a running average of the last 8.
197 size += pixy.blocks[trackedBlock].width * pixy.blocks[trackedBlock].height;
198 size -= size >> 3;
199
200 // Forward speed decreases as we approach the object (size is larger)
201 int forwardSpeed = constrain(400 - (size/256), -100, 400);
202
203 // Steering differential is proportional to the error times the forward speed
204 int32_t differential = (followError + (followError * forwardSpeed))>>8;
205
206 // Adjust the left and right speeds by the steering differential.
207 int leftSpeed = constrain(forwardSpeed + differential, -400, 400);
208 int rightSpeed = constrain(forwardSpeed - differential, -400, 400);
209
210 // And set the motor speeds
211 motors.setLeftSpeed(leftSpeed);
212 motors.setRightSpeed(rightSpeed);
213}
214
215//---------------------------------------
216// Random search for blocks
217//
218// This code pans back and forth at random
219// until a block is detected
220//---------------------------------------
221int scanIncrement = (RCS_MAX_POS - RCS_MIN_POS) / 150;
222uint32_t lastMove = 0;
223
224void ScanForBlocks()
225{
226 if (millis() - lastMove > 20)
227 {
228 lastMove = millis();
229 panLoop.m_pos += scanIncrement;
230 if ((panLoop.m_pos >= RCS_MAX_POS)||(panLoop.m_pos <= RCS_MIN_POS))
231 {
232 tiltLoop.m_pos = random(RCS_MAX_POS * 0.6, RCS_MAX_POS);
233 scanIncrement = -scanIncrement;
234 if (scanIncrement < 0)
235 {
236 motors.setLeftSpeed(-250);
237 motors.setRightSpeed(250);
238 }
239 else
240 {
241 motors.setLeftSpeed(+180);
242 motors.setRightSpeed(-180);
243 }
244 delay(random(250, 500));
245 }
246
247 pixy.setServos(panLoop.m_pos, tiltLoop.m_pos);
248 }
249}
Note: See TracBrowser for help on using the repository browser.