-
Notifications
You must be signed in to change notification settings - Fork 1
/
_Phoenix.h
295 lines (243 loc) · 9.79 KB
/
_Phoenix.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
//=============================================================================
//Project Lynxmotion Phoenix
//Description: Phoenix software
//
//Programmer: Jeroen Janssen [aka Xan]
// Kurt Eckhardt(KurtE) converted to C and Arduino
// Kare Halvorsen aka Zenta - Makes everything work correctly!
//
// This version of the Phoenix code was ported over to the Arduino Environement
//
//
// Phoenix.h - This is the first header file that is needed to build
// a Phoenix program for a specific Hex Robot.
//
//
// This file assumes that the main source file either directly or through include
// file has defined all of the configuration information for the specific robot.
// Each robot will also need to include:
//
//=============================================================================
//
//KNOWN BUGS:
// - Lots ;)
//
//=============================================================================
//==============================================================================
#ifndef _PHOENIX_CORE_H_
#define _PHOENIX_CORE_H_
#include <stdarg.h>
#ifdef USEXBEE
#include "diyxbee.h"
#endif
//=============================================================================
//[CONSTANTS]
//=============================================================================
#define BUTTON_DOWN 0
#define BUTTON_UP 1
#define c1DEC 10
#define c2DEC 100
#define c4DEC 10000
#define c6DEC 1000000
#ifdef QUADMODE
enum {
cRR = 0, cRF, cLR, cLF, CNT_LEGS
};
#elif defined(OCTOMODE)
enum {
cRR = 0, cRMR, cRMF, cRF, cLR, cLMR, cLMF, cLF, CNT_LEGS
};
#else
enum {
cRR = 0, cRM, cRF, cLR, cLM, cLF, CNT_LEGS
};
#endif
#define WTIMERTICSPERMSMUL 64 // BAP28 is 16mhz need a multiplyer and divider to make the conversion with /8192
#define WTIMERTICSPERMSDIV 125 //
#define USEINT_TIMERAV
// BUGBUG: to make Dynamic first pass simpl make it a variable.
extern byte NUM_GAITS;
#define SmDiv 4 //"Smooth division" factor for the smooth control function, a value of 3 to 5 is most suitable
extern void GaitSelect(void);
extern short SmoothControl(short CtrlMoveInp, short CtrlMoveOut, byte CtrlDivider);
//-----------------------------------------------------------------------------
// Define Global variables
//-----------------------------------------------------------------------------
extern boolean g_fDebugOutput;
extern boolean g_fEnableServos; // Hack to allow me to turn servo processing off...
extern boolean g_fRobotUpsideDown; // Is the robot upside down?
extern void MSound(byte cNotes, ...);
extern boolean CheckVoltage(void);
extern word GetLegsXZLength(void);
extern void AdjustLegPositions(word XZLength1);
extern void AdjustLegPositionsToBodyHeight();
extern void ResetLegInitAngles(void);
extern void RotateLegInitAngles(int iDeltaAngle);
extern long GetCmdLineNum(byte** ppszCmdLine);
// debug handler...
extern boolean g_fDBGHandleError;
#ifdef c4DOF
extern const byte cTarsLength[];
#endif
#ifdef OPT_BACKGROUND_PROCESS
#define DoBackgroundProcess() g_ServoDriver.BackgroundProcess()
#else
#define DoBackgroundProcess()
#endif
#ifdef DEBUG_IOPINS
#define DebugToggle(pin) {digitalWrite(pin, !digitalRead(pin));}
#define DebugWrite(pin, state) {digitalWrite(pin, state);}
#else
#define DebugToggle(pin) {;}
#define DebugWrite(pin, state) {;}
#endif
//=============================================================================
//=============================================================================
// Define the class(s) for our Input controllers.
//=============================================================================
//=============================================================================
class InputController {
public:
virtual void Init(void);
virtual void ControlInput(void);
virtual void AllowControllerInterrupts(boolean fAllow);
#ifdef OPT_TERMINAL_MONITOR_IC // Allow Input controller to define stuff as well
void ShowTerminalCommandList(void);
boolean ProcessTerminalCommand(byte* psz, byte bLen);
#endif
private:
}
;
// Define a function that allows us to define which controllers are to be used.
extern void RegisterInputController(InputController* pic);
typedef struct _Coord3D {
long x;
long y;
long z;
}
COORD3D;
//==============================================================================
// Define Gait structure/class - Hopefully allow specific robots to define their
// own gaits and/or define which of the standard ones they want.
//==============================================================================
typedef struct _PhoenixGait {
short NomGaitSpeed; //Nominal speed of the gait
byte StepsInGait; //Number of steps in gait
byte NrLiftedPos; //Number of positions that a single leg is lifted [1-3]
byte FrontDownPos; //Where the leg should be put down to ground
byte LiftDivFactor; //Normaly: 2, when NrLiftedPos=5: 4
byte TLDivFactor; //Number of steps that a leg is on the floor while walking
byte HalfLiftHeight; // How high to lift at halfway up.
#ifdef QUADMODE
// Extra information used in the Quad balance mode
word COGAngleStart1; // COG shifting starting angle
word COGAngleStep1; // COG Angle Steps in degrees
byte COGRadius; // COG Radius; the amount the body shifts
boolean COGCCW; // COG Gait sequence runs counter clock wise
#endif
byte GaitLegNr[CNT_LEGS]; //Init position of the leg
#ifdef DISPLAY_GAIT_NAMES
const char* pszName; // The gait name
#endif
}
PHOENIXGAIT;
#ifdef DISPLAY_GAIT_NAMES
#define GATENAME(name) ,name
#else
#define GATENAME(name)
#endif
//==============================================================================
// class ControlState: This is the main structure of data that the Control
// manipulates and is used by the main Phoenix Code to make it do what is
// requested.
//==============================================================================
typedef struct _InControlState {
boolean fRobotOn; //Switch to turn on Phoenix
boolean fPrev_RobotOn; //Previous loop state
//Body position
COORD3D BodyPos;
COORD3D BodyRotOffset; // Body rotation offset;
//Body Inverse Kinematics
COORD3D BodyRot1; // X -Pitch, Y-Rotation, Z-Roll
//[gait]
byte GaitType; //Gait type
byte GaitStep; //Actual current step in gait
PHOENIXGAIT gaitCur; // Definition of the current gait
short LegLiftHeight; //Current Travel height
COORD3D TravelLength; // X-Z or Length, Y is rotation.
#ifdef cTurretRotPin
// Turret information
int TurretRotAngle1; // Rotation of turrent in 10ths of degree
int TurretTiltAngle1; // the tile for the turret
#endif
//[Single Leg Control]
#ifdef OPT_SINGLELEG
byte SelectedLeg;
byte PrevSelectedLeg;
COORD3D SLLeg; //
boolean fSLHold; //Single leg control mode
#endif
//[Balance]
boolean BalanceMode;
//[TIMING]
byte InputTimeDelay; //Delay that depends on the input to get the "sneaking" effect
word SpeedControl; //Adjustible Delay
byte ForceGaitStepCnt; // new to allow us to force a step even when not moving
#ifdef OPT_DYNAMIC_ADJUST_LEGS
short aCoxaInitAngle1[CNT_LEGS];
#endif
//
}
INCONTROLSTATE;
//==============================================================================
//==============================================================================
// Define the class(s) for Servo Drivers.
//==============================================================================
//==============================================================================
class ServoDriver {
public:
boolean Init(void);
boolean InitServos();
boolean inline ServosInit();
void ServoPowerWentLow();
word GetBatteryVoltage(void);
void BeginServoUpdate(void); // Start the update
#ifdef c4DOF
void OutputServoInfoForLeg(byte LegIndex, short sCoxaAngle1, short sFemurAngle1, short sTibiaAngle1, short sTarsAngle1);
#else
void OutputServoInfoForLeg(byte LegIndex, short sCoxaAngle1, short sFemurAngle1, short sTibiaAngle1);
#endif
#ifdef cTurretRotPin
void OutputServoInfoForTurret(short sRotateAngle1, short sTiltAngle1);
#endif
void CommitServoDriver(word wMoveTime);
void FreeServos(void);
void IdleTime(void); // called when the main loop when the robot is not on
// Allow for background process to happen...
#ifdef OPT_BACKGROUND_PROCESS
void BackgroundProcess(void);
#endif
#ifdef OPT_TERMINAL_MONITOR
void ShowTerminalCommandList(void);
boolean ProcessTerminalCommand(byte* psz, byte bLen);
#endif
private:
}
;
//==============================================================================
//==============================================================================
// Define global class objects
//==============================================================================
//==============================================================================
extern ServoDriver g_ServoDriver; // our global servo driver class
extern InputController g_InputController; // Our Input controller
extern INCONTROLSTATE g_InControlState; // State information that controller changes
#ifndef min
#define min(a, b) (((a)<=(b))? (a):(b))
#define max(a, b) (((a)>=(b))? (a):(b))
#endif
#ifdef OPT_MEMORY_USAGE
extern void initMemoryUsageTest();
extern void printMemoryUsage();
#endif //OPT_MEMORY_USAGE
#endif