<repo_name>Kyle-Xu001/ROS-Practice<file_sep>/assignment1/src/turtle_circle.cpp
#include <ros/ros.h>
#include <turtlesim/Pose.h>
#include <geometry_msgs/Twist.h>

//callback function
void chatterCallback(const turtlesim::Pose& msg){
    ROS_INFO("Turtle is at [%f, %f, %f]", (float)(msg.x), (float)(msg.y), (float)(msg.theta));
}


int main(int argc, char **argv){
    ros::init(argc, argv, "turtle_circle");

    ros::NodeHandle n;

    ros::Publisher turtle_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel",1);
    ros::Subscriber turtle_sub = n.subscribe("/turtle1/pose", 1, chatterCallback);
    ros::Rate loop_rate(10);
    while(ros::ok()){
        geometry_msgs::Twist msg;
        msg.linear.x = 1;
        msg.linear.y = 0;
        msg.linear.z = 0;
        msg.angular.x = 0;
        msg.angular.y = 0;
        msg.angular.z = 1;
        turtle_pub.publish(msg);
        ros::spinOnce();
        loop_rate.sleep();
            }
    return 0;
}<file_sep>/README.md
# ROS-Practice
This repository is created for programming assignments in ***ROS Theory and Practice***, which includes functional nodes and extended functions.  

## Assignment1
This part is about communication programming, which includes applications on publisher, subscriber, server and client.  
The function of each node is defined as follows:  
**turtle_call**:  Create a new turtle at specific location predefined in the code.   
**turtle_circle**: Control the existed turtle in circular motion, and subscribe the pose of turtle in real time.  
**turtle_control**: Control the real-time motion of existed turtle by inputting turtle name and velocity parameters in command line. (*Achieved by **Publisher** function*)  
**turtle_spawn**: Create a new turtle at a random location with the name defined in command line. (*Achieved by single **Client** function*)  
**turtle_spawn_client / turtle_spawn_server**： Create a new turtle at a random location with the name defined in command line. (*Achieved by combination of **Server** and **Client***)    
<file_sep>/assignment1/src/turtle_call.cpp
#include <ros/ros.h>
#include <turtlesim/Spawn.h>

int main(int argc, char **argv){

    ros::init(argc, argv, "turtle_call");
    ros:: NodeHandle n;

    ros::service::waitForService("/spawn");
    ros::ServiceClient client = n.serviceClient<turtlesim::Spawn>("/spawn");

    turtlesim::Spawn srv;
    srv.request.x = 5.0;
    srv.request.y = 5.0;
    srv.request.theta = 0;
    srv.request.name = "Bob";
    
    ROS_INFO("Call service to spawn a turtle at [%f, %f], name %s", (float)(srv.request.x), (float)(srv.request.y), srv.request.name.c_str());
    client.call(srv);
    ROS_INFO("Turtle Spawn: OK!");


    return 0;
}<file_sep>/assignment1/src/turtle_spawn.cpp
#include <ros/ros.h>
#include <turtlesim/Spawn.h>
#include <iostream>
#include <ctime>

int main(int argc, char **argv){
    //Set the real random seed
    srand((unsigned int)time(NULL));

    //Initiate the ROS node
    ros::init(argc, argv, "turtle_spawn");
    ros::NodeHandle n;

    //Construct the service client to call service "spawn"
    ros::service::waitForService("/spawn");
    ros::ServiceClient client = n.serviceClient<turtlesim::Spawn>("/spawn");

    //Define the request msg
    turtlesim::Spawn srv;
    srv.request.x = 0.5 + (rand()%100) / 10;
    srv.request.y = 0.5 + (rand()%100) / 10 ;
    srv.request.theta = rand()%360;

    //Input the name in command line and transfer to request
    std::string name;
    ROS_INFO("Please input the turtle name: ");
    std::getline(std::cin, name); 
    srv.request.name = name;

    if (client.call(srv)){
        ROS_INFO("Response: [%s]", srv.request.name.c_str());
    }else{
        ROS_INFO("Failed to create a turtle!");
    }

    return 0;
}<file_sep>/assignment1/src/turtle_spawn_server.cpp
#include <ros/ros.h>
#include <assignment1/turtlecall.h>
#include <turtlesim/Spawn.h>
#include <ctime>

class turtlecall{
public:
    turtlecall(){
        client = n.serviceClient<turtlesim::Spawn>("/spawn");
        service= n.advertiseService("/turtlecall", &turtlecall::Callback,this);


    }
    bool Callback(assignment1::turtlecall::Request &req, assignment1::turtlecall::Response &res){
    srand((unsigned int)time(NULL));
    turtlesim::Spawn srv;
    srv.request.x = 0.5 + (rand()%100)/10;
    srv.request.y = 0.5 + (rand()%100)/10;
    srv.request.theta = rand()%360;
    srv.request.name = req.name;

    if (client.call(srv)){
        ROS_INFO("Successfully call a turtle!");
        res.result = "Success!";
    }else{
        res.result = "Wrong!";
    }
    return true;
}
private:
    ros::NodeHandle n;
    ros::ServiceClient client;
    ros::ServiceServer service;
};

int main(int argc, char **argv){

    ros::init(argc, argv, "turtlecall_service");

    ros::service::waitForService("/spawn");
    ROS_INFO("Ready to call the turtle");
    turtlecall A;
    ros::spin();


    return 0;
}<file_sep>/assignment1/src/turtle_spawn_client.cpp
#include <ros/ros.h>
#include <turtlesim/Spawn.h>
#include <assignment1/turtlecall.h>
#include<iostream>

int main(int argc, char **argv){
    ros::init(argc, argv, "turtlecall_client");
    ros::NodeHandle n;

    ros::service::waitForService("/turtlecall");
    ros::ServiceClient client = n.serviceClient<assignment1::turtlecall>("/turtlecall");

    assignment1::turtlecall srv;

    std::string name;
    ROS_INFO("Please input the turtle name:");
    std::getline(std::cin,name);
    srv.request.name = name;

    ROS_INFO("Call service to add a turtle [%s]",srv.request.name.c_str());
    client.call(srv);

    ROS_INFO("Show response: [%s]",srv.response.result.c_str());



    return 0;
}<file_sep>/assignment1/src/turtle_control.cpp
#include <ros/ros.h>
#include <geometry_msgs/Twist.h> 
#include <iostream>

int main(int argc, char **argv){
    ros::init(argc, argv, "turtle_control");
    ros::NodeHandle n;


    ROS_INFO("Please input the target turtle:");
    std::string name;
    std::getline(std::cin, name);
    ros::Publisher pub = n.advertise<geometry_msgs::Twist>("/"+name+"/cmd_vel",1);
    ros::Rate loop_rate(10);

    ROS_INFO("Please input the angular velocity of turtle:");
    double w;
    std::cin>>w;

    ROS_INFO("Please input the linear velocity of turtle:");
    double x;
    std::cin>>x;

    geometry_msgs::Twist msg;
    msg.linear.x = (double)x;
    msg.linear.y = 0;
    msg.linear.z = 0;
    msg.angular.x = 0;
    msg.angular.y = 0;
    msg.angular.z = (double)w;
    
    while (ros::ok()){
        pub.publish(msg);
        loop_rate.sleep();
    }

    return 0;
}