18 robot_->enableRobot();
25 this->standStraight(500);
29 this->arms(arm_pos, arm_pos);
33 float batt = robot_->getBattery();
54 if (l == 4) {moveJoint(data[1], data[2], data[3]);}
55 if (l == 5) {moveJoint(data[1], data[2], data[3], data[4]);}
break;
57 if (l == 2) {lean(data[1]);}
if (l == 3) {lean(data[1], data[2]);}
58 if (l == 4) {lean(data[1], data[2], data[3]);}
break;
60 if (l == 2) {walk(data[1]);}
if (l == 3) {walk(data[1], data[2]);}
61 if (l == 4) {walk(data[1], data[2], data[3]);}
62 if (l == 5) {walk(data[1], data[2], data[3], data[4]);}
63 if (l == 6) {walk(data[1], data[2], data[3], data[4], data[5]);}
break;
65 if (l == 2) {kick(data[1]);}
if (l == 3) {kick(data[1], data[2]);}
break;
67 if (l == 1) {eyes();}
if (l == 2) {eyes(data[1]);}
68 if (l == 3) {eyes(data[1], data[2]);}
break;
70 if (l == 2) {celebrate(data[1]);}
break;
72 if (l == 2) {liftLeg(data[1]);}
if (l == 3) {liftLeg(data[1], data[2]);}
73 if (l == 4) {liftLeg(data[1], data[2], data[3]);}
break;
75 if (l == 2) {lowerLeg(data[1]);}
break;
77 dance(data[1]);
break;
80 if (l == 2) {arms(data[1]);}
if (l == 3) {arms(data[1], data[2]);}
break;
82 case CMD_GET:
if (l == 3) {getData(data[1], data[2]);}
break;
84 if (l == 2) {sideStep(data[1]);}
if (l == 3) {sideStep(data[1], data[2]);}
85 if (l == 4) {sideStep(data[1], data[2], data[3]);}
86 if (l == 5) {sideStep(data[1], data[2], data[3], data[4]);}
break;
88 if (l == 1) {standStraight();}
if (l == 2) {standStraight(data[1]);}
break;
90 playSounds(data);
break;
93 ROS_ERROR_STREAM(
"CmdServer did not recognise command " << data[0]);
break;
99 if ((data.size() % 4) != 0) {ROS_ERROR(
"Data Package wrong size!");}
else {
100 vector<int> cmd_data;
101 for (
int i = 0; i < (data.size() / 4); ++i) {
103 cmd_data.push_back(0);
104 memcpy(&cmd_data[i], &data[(i * 4)], 4);
108 if (!busy_) { runCommand(cmd_data); }
109 else { cmd_queue_.push_back(cmd_data); }
129 float step_time = ((float) move_time) / 1000;
130 bool leftFoot =
false;
131 if (side ==
CMD_LEFT) { leftFoot =
true; }
132 else if (side ==
CMD_RIGHT) { leftFoot =
false; }
else {
134 if (robot_->jangles_[
RHIP] < robot_->jangles_[
LHIP]) { leftFoot =
true; }
136 if (step_length < 0) { leftFoot = !leftFoot; }
138 if ((turn_spot_) && ((abs(turn) > 0) && (step_length == 0)))
139 { leftFoot = !leftFoot; turn_spot_ =
false; }
140 else if ((abs(turn) > 0) && (step_length == 0)) { turn_spot_ =
true; }
141 else { turn_spot_ =
false; }
143 for (
int step_num = 0; step_num < num_steps; step_num++) {
145 tInterp =
genStepLeft(robot_, step_length, turn, step_time);
147 tInterp =
genStepRight(robot_, step_length, turn, step_time);
150 leftFoot = !leftFoot;
156 float kicktime = ((float)move_time) / 1000;
168 robot_->setServo(
EYES, amount);
172 resp_request_ =
true;
174 if ((
id >= 8) || (
id < 0)) {resp_request_ =
false;}
175 else { val_request_ = gpio_data_.gpio[id]; }
177 if (
id ==
AXES_X) { val_request_ = accel_data_.x;}
178 else if (
id ==
AXES_Y) { val_request_ = accel_data_.y;}
179 else if (
id ==
AXES_Z) { val_request_ = accel_data_.z;}
180 else {resp_request_ =
false;}
182 val_request_ = batt_data_.data;
184 if ((
id >= 8) || (
id < 0)) {resp_request_ =
false;}
185 else { val_request_ = curr_data_.current[id]; }
187 if (
id ==
AXES_X) { val_request_ = ball_pos_.x;}
188 else if (
id ==
AXES_Y) { val_request_ = ball_pos_.y;}
190 resp_request_ =
false;
195 data_t tSetpoints, tInterp;
196 deque<float> tline(robot_->jangles_); tline.push_front(0);
199 tSetpoints.clear(); tSetpoints.push_back(tline);
200 if (joint ==
J_HIP) {
202 tline[1 +
LHIP] = (float)amount;
204 tline[1 +
RHIP] = (float)amount;
208 tline[1 +
LTWIST] = (float)amount;
210 tline[1 +
RTWIST] = (float)amount;
212 }
else if (joint ==
J_KNEE) {
214 tline[1 +
LKNEE] = (float)amount;
216 tline[1 +
RKNEE] = (float)amount;
218 }
else if (joint ==
J_LEG) {
220 tline[1 +
LHIP] = (float)amount;
222 tline[1 +
RHIP] = (float)amount;
224 }
else if (joint ==
J_ARM) {
226 tline[1 +
LARM] = (float)amount;
228 tline[1 +
RARM] = (float)amount;
230 }
else if (joint ==
J_EYES) {
231 tline[1 +
EYES] = (float)amount;
233 tline[0] = ((float)move_time) / 1000; tSetpoints.push_back(tline);
239 data_t tSetpoints, tInterp; deque<float> tline(robot_->jangles_);
240 tline.push_front(0); tSetpoints.push_back(tline);
241 float lean_time = ((float)move_time) / 1000;
254 robot_->celebSound(1.6);
262 data_t tSetpoints, tInterp; deque<float> tline(robot_->jangles_);
263 tline.push_front(0); tSetpoints.clear(); tSetpoints.push_back(tline);
265 tline[1 +
LKNEE] = tline[1 +
RKNEE] + (float)amount;
267 tline[1 +
RKNEE] = tline[1 +
LKNEE] - (float)amount;
269 tline[0] = ((float)move_time) / 1000; tSetpoints.push_back(tline);
280 data_t tSetpoints, tInterp; deque<float> tline(robot_->jangles_);
281 tline.push_front(0); tSetpoints.push_back(tline);
283 if (abs(robot_->jangles_[
RKNEE]) > abs(robot_->jangles_[
LKNEE])) {
285 if (robot_->jangles_[
RKNEE] < 0) {
286 tline[1 +
RKNEE] = 0 - abs(robot_->jangles_[
LKNEE]);
288 tline[1 +
RKNEE] = abs(robot_->jangles_[
LKNEE]);
291 if (robot_->jangles_[
LKNEE] < 0) {
292 tline[1 +
LKNEE] = 0 - abs(robot_->jangles_[
RKNEE]);
294 tline[1 +
LKNEE] = abs(robot_->jangles_[
RKNEE]);
297 tline[0] = ((float)move_time) / 1000; tSetpoints.push_back(tline);
303 if (robot_id < 0) { robot_id = 0; }
if (robot_id > 2) { robot_id = 2; }
308 std::map<int, float> angles = {{
RARM, (float)r_angle}, {
LARM, (float)l_angle}};
309 robot_->setServos(angles);
315 std::map<int, float> angles;
317 angles[i] = robot_->jangles_[i];
329 for (alpha = 0; alpha < 6.28; alpha += 0.1) {
334 this->swingArms(100, 100, 2000, 8);
335 this->swingArms(100, -100, 2000, 8);
337 marty_msgs::ServoMsgArray h_array;
338 marty_msgs::ServoMsg r_hip; r_hip.servo_id =
RHIP; r_hip.servo_cmd = 45;
339 marty_msgs::ServoMsg l_hip; l_hip.servo_id =
LHIP; l_hip.servo_cmd = 45;
340 h_array.servo_msg.push_back(r_hip); h_array.servo_msg.push_back(l_hip);
341 this->swingJoints(h_array, 2000, 8);
344 for (alpha = 0; alpha < 12.56; alpha += 0.1) {
345 angles[
RHIP] = 45 * sin(alpha); angles[
LHIP] = angles[
RHIP];
346 robot_->setServos(angles);
351 for (alpha = 0; alpha < 12.56; alpha += 0.1) {
353 robot_->setServos(angles);
360 for (alpha = 0; alpha < 12.56; alpha += 0.1) {
362 robot_->setServos(angles);
368 for (alpha = 0; alpha < 12.56; alpha += 0.1) {
370 robot_->setServos(angles);
379 for (
int numstep = 0; numstep < 1; numstep++) {
389 for (
int numstep = 0; numstep < 2; numstep++) {
408 robot_->celebSound(1.4);
428 if (duration <= 0) { duration = 2000; }
429 if (cycles <= 0) { cycles = 4; }
431 int steps = duration / delay;
433 std::map<int, float> angles;
435 angles[i] = robot_->jangles_[i];
438 float inc = (1.57 * cycles) / steps;
439 for (
int s = 0; s < steps; ++s) {
440 angles[
RARM] = r_arm * sin(alpha);
441 angles[
LARM] = l_arm * sin(alpha);
442 robot_->setServos(angles);
450 if (duration <= 0) { duration = 2000; }
451 if (cycles <= 0) { cycles = 4; }
453 int steps = duration / delay;
455 std::map<int, float> angles;
457 angles[i] = robot_->jangles_[i];
460 float inc = (1.57 * cycles) / steps;
461 for (
int s = 0; s < steps; ++s) {
462 for (
int i = 0; i < servo_array.servo_msg.size(); ++i) {
463 angles[servo_array.servo_msg[i].servo_id] =
464 servo_array.servo_msg[i].servo_cmd * sin(alpha);
466 robot_->setServos(angles);
475 int opp_side = 1 - side;
476 if (side ==
CMD_LEFT) {step_length = -step_length;}
477 for (
int step = 0; step < num_steps; ++step) {
478 this->moveJoint(side,
J_KNEE, -step_length, (move_time / 4));
479 this->moveJoint(opp_side,
J_KNEE, step_length, (move_time / 4));
480 this->moveJoint(side,
J_KNEE, 0, (move_time / 4));
481 this->moveJoint(opp_side,
J_KNEE, 0, (move_time / 4));
483 }
else { ROS_ERROR(
"Can only sidestep left or right"); }
487 data_t tSetpoints, tInterp; deque<float> tline(robot_->jangles_);
488 tline.push_front(0); tSetpoints.push_back(tline);
489 float straight_time = ((float)move_time) / 1000;
500 marty_msgs::SoundArray sound_msg;
501 if (((sounds.size() - 1) % 3) != 0) {
502 ROS_WARN(
"Received wrong number of sound arguments!");
504 for (
int s = 0; s < ((sounds.size() - 1) / 3); ++s) {
505 marty_msgs::Sound sound;
507 sound.freq1 = sounds[i];
508 sound.duration = ((float)sounds[i + 1] / 1000);
509 sound.freq2 = sounds[i + 2];
510 sound_msg.sound.push_back(sound);
512 robot_->playSoundArray(sound_msg);
524 ROS_WARN(
"EXITING!");
525 ros::param::del(
"/marty");
534 ROS_INFO(
"CmdServer Ready!");
538 ros::param::del(
"/marty");
543 nh_.param(
"launched", launched,
false);
545 ROS_ERROR(
"Please use 'roslaunch ros_marty marty.launch'\n");
570 marty_msgs::Command::Response& res) {
572 else { res.success =
false; }
578 struct sockaddr_in servaddr;
579 sock_ = socket(AF_INET, SOCK_STREAM, 0);
580 if (sock_ < 0) { ROS_ERROR(
"cannot create socket"); ros::shutdown(); }
582 setsockopt(sock_, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(
int));
584 memset((
char*)&servaddr, 0,
sizeof(servaddr));
585 servaddr.sin_family = AF_INET;
586 servaddr.sin_addr.s_addr = INADDR_ANY;
587 servaddr.sin_port = htons(
PORT);
588 if (bind(sock_, (
struct sockaddr*) &servaddr,
sizeof(servaddr)) < 0)
589 { ROS_ERROR(
"ERROR on binding"); ros::shutdown(); }
593 fcntl(sock_, F_SETFL, O_NONBLOCK);
594 printf(
"Socket initialised on port: %d. Waiting for incoming connection\n",
603 struct sockaddr_in clientaddr;
605 char const* resp_msg =
"";
606 socklen_t clilen =
sizeof(clientaddr);
607 int clisock = accept(
sock_, (
struct sockaddr*) &clientaddr, &clilen);
610 ROS_DEBUG(
"Incoming connection accepted...\n");
611 int nbytes = read(clisock, buffer, 4096);
613 ROS_DEBUG(
"Data received: %d", buffer[0]);
614 vector<int8_t> dbytes;
615 dbytes.push_back(buffer[0]);
616 for (
int i = 1; i < nbytes; i++) {
617 ROS_DEBUG(
"\t%d", buffer[i]);
618 dbytes.push_back(buffer[i]);
620 ROS_DEBUG(
"Running Command\n");
622 if (dbytes[0] ==
CMD_GET) {
get =
true; }
624 ROS_WARN(
"Marty has fallen over! Please pick him up and try again.");
628 resp_msg =
"Success";
630 ROS_DEBUG(
"Done!\n");
636 write(clisock, resp_msg, strlen(resp_msg));
641 ROS_WARN(
"Marty has fallen over! Please pick him up and try again.");
651 ROS_WARN(
"Marty has fallen over! Please pick him up and try again.");
654 ROS_INFO_STREAM(
"RUNNING NEXT CMD: " <<
cmd_queue_[0][0]);
661 int main(
int argc,
char** argv) {
663 ros::init(argc, argv,
"cmd_server");
671 while (ros::ok() && !
exiting) {
void sideStep(int side, int num_steps=1, int move_time=1000, int step_length=50)
void arms(int r_angle=0, int l_angle=0)
void sitBack(int duration)
bool setPointsLeanBackward(data_t &tSetpoints, int leanAmount, float period)
ros::Subscriber curr_sub_
void moveJoint(int side, int joint, int amount, int move_time=2000)
data_t genStepLeft(MartyCore *robot, int stepLength, int turn, float period)
void liftLeg(int leg, int amount=100, int move_time=2000)
void walk(int num_steps=2, int turn=0, int move_time=3000, int step_length=50, int side=-1)
std::vector< int > cmd_data_
bool setPointsLeanForward(data_t &tSetpoints, int leanAmount, float period)
void swingArms(int r_arm, int l_arm, int duration=2000, int cycles=4)
ros::ServiceServer cmd_srv_
volatile sig_atomic_t exiting
void runCommand(vector< int > data)
Runs commands received by the server.
void accelCB(const marty_msgs::Accelerometer &msg)
void ballCB(const geometry_msgs::Pose2D &msg)
bool setPointsLeanLeft(data_t &tSetpoints, int leanAmount, float period)
CmdServer(ros::NodeHandle &nh)
ros::Subscriber batt_sub_
void celebrate(int move_time=4000)
ros::Subscriber gpio_sub_
void eyes(int amount=0, int amount2=0)
ros::Subscriber ball_sub_
data_t genStepRight(MartyCore *robot, int stepLength, int turn, float period)
data_t genKickLeft(MartyCore *robot, float period)
void testLeg(int side, int duration)
CMD Server for Marty, enabling execution of CMDs remotely.
bool runTrajectory(MartyCore *robot, data_t &traj)
bool setPointsLegsZero(data_t &tSetpoints, float period)
int main(int argc, char **argv)
void runSockCommand(vector< int8_t > data)
data_t genSitBack(MartyCore *robot, float period)
bool cmd_service(marty_msgs::Command::Request &req, marty_msgs::Command::Response &res)
data_t genCelebration(MartyCore *robot, float move_time)
bool interpTrajectory(data_t tIn, data_t &tOut, float dt)
void getData(int sensor, int id)
bool setPointsLeanRight(data_t &tSetpoints, int leanAmount, float period)
int hipToBeSquare(MartyCore *robot, int robotID)
std::vector< std::vector< int > > cmd_queue_
void kick(int side=CMD_LEFT, int move_time=3000)
data_t genKickRight(MartyCore *robot, float period)
void swingJoints(marty_msgs::ServoMsgArray, int duration=2000, int cycles=4)
int rollerSkate(MartyCore *robot)
void currCB(const marty_msgs::MotorCurrents &msg)
data_t genRaisedFootTwistRight(MartyCore *robot, float period)
data_t genRaisedFootTwistLeft(MartyCore *robot, float period)
void playSounds(std::vector< int > sounds)
void standStraight(int move_time=1000)
void battCB(const std_msgs::Float32 &msg)
void gpioCB(const marty_msgs::GPIOs &msg)
void lean(int dir, int amount=100, int move_time=2000)
void robotReady()
Robot motion executed when cmdServer is ready.
ros::Subscriber accel_sub_
void lowerLeg(int move_time=1000)
data_t genReturnToZero(MartyCore *robot, float period)