控制的开环和闭环-turtlesim

基本概念:

开环控制是一种控制系统,它根据预先设定的输入来控制输出,而不考虑实际输出的影响。在turtlesim中,开环控制可以用来控制海龟机器人的运动,例如控制它向前或向后移动、旋转等。

闭环控制是一种控制系统,它通过反馈机制来调整输出,以使系统达到期望的状态。在turtlesim中,闭环控制可以用来控制海龟机器人的运动,以使其达到预定的目标位置和方向。

机器人系统开环控制是一种控制方法,它不考虑系统的反馈信息,只根据输入信号直接控制输出信号。这种控制方法适用于一些简单的系统,但对于复杂的系统来说,闭环控制更为常用。

机器人系统闭环控制是指通过传感器获取机器人当前状态,然后根据预设的控制算法进行控制,最终达到期望的目标。这个过程中需要不断地进行反馈和调整,以保证机器人的稳定性和精度。如果您需要更具体的信息,可以提供更详细的问题描述。

机器人系统开环控制和闭环控制的区别在于反馈控制的有无。开环控制是指机器人系统只根据输入信号进行操作,没有反馈控制,无法对输出进行调整。而闭环控制则是在开环控制的基础上加入了反馈控制,通过对输出进行测量和比较,对输入进行调整,以达到更精确的控制效果。

以下是ROS机器人turtlesim的开环控制代码:

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
int main(int argc, char** argv){
    ros::init(argc, argv, "turtlesim_open_loop_control");
    ros::NodeHandle nh;
    ros::Publisher pub = nh.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 1000);
    ros::Rate rate(10);
    while(ros::ok()){
        geometry_msgs::Twist msg;
        msg.linear.x = 1.0; // 设置线速度为1.0
        msg.angular.z = 1.0; // 设置角速度为1.0
        pub.publish(msg);
        rate.sleep();
    }
    return 0;
}

于是有了下面:

优美的曲线-turtlesim

绘制曲线如果采用开环则无法保准精确的。

调整参数可以获得对应精度的曲线。通常参数调整需要考虑绘制速度和效果的平衡。

高精度-通常而言机器人绘制曲线速度较慢

低精度-绘制速度能得到极大提升

很多控制指标并非统一,更多时候是一种折衷选择。

例如:机器人最优路径规划是指在给定的地图和起点、终点的情况下,通过算法计算出机器人行走的最短路径或最优路径。这个问题可以通过使用图论算法来解决,比如 Dijkstra 算法、A*算法等。这些算法会根据地图上的节点和边的权重来计算出最短路径或最优路径。在实际应用中,机器人最优路径规划可以用于自动驾驶、物流配送、智能家居等领域。

机器人最优轨迹规划是指在给定机器人的起点和终点以及环境的限制条件下,通过算法计算出机器人在运动过程中的最优路径。最优路径可以是最短路径、最快路径、最安全路径等,取决于具体的应用场景和需求。常用的机器人轨迹规划算法包括 A*算法、Dijkstra算法、RRT算法等。这些算法可以通过对机器人运动学模型的建模和对环境的建模来实现。

机器人最优运动规划是指在给定的环境下,通过算法计算出机器人在运动过程中最优的路径和速度规划,以达到最高效的运动效果。这个问题涉及到机器人技术和算法。机器人最优运动控制是指在给定的运动任务下,通过优化算法,使机器人在满足运动要求的同时,达到最优的运动效果。这个问题涉及到机器人控制、优化算法等方面的知识,需要结合具体的应用场景进行分析和解决。

蓝桥ROS机器人之turtlesim贪吃蛇

git clone https://gitcode.net/ZhangRelay/cocubesim.git

键盘遥控-开环:


贪吃蛇-后方机器人跟随-闭环:


启动move节点,不关闭键盘遥控:

关闭键盘遥控:



参考代码:

import rospy
from turtlesim.msg import Pose
from turtlesim.srv import Spawn
from turtlesim.srv import SetPen
from geometry_msgs.msg import Twist
from geometry_msgs.msg import TransformStamped
import random
import math

turtle1_pose = Pose()
turtlelist = []
lastturtle = 1
nextturtleIndex = 1

class mySpawner:
    def __init__(self, tname):
        self.turtle_name = tname
        self.state = 1
        rospy.wait_for_service('/spawn')
        try:
            client = rospy.ServiceProxy('/spawn', Spawn)
            x = random.randint(1, 10)
            y = random.randint(1, 10)
            theta = random.uniform(1, 3.14)
            name = tname
            _nm = client(x, y, theta, name)
            rospy.loginfo("turtle Created [%s] [%f] [%f]", name, x, y)
            rospy.Subscriber(self.turtle_name + '/pose', Pose, self.turtle_poseCallback)
            self.pub = rospy.Publisher(self.turtle_name + '/cmd_vel', Twist, queue_size=10)
            self.turtle_to_follow = 1
            self.turtle_pose = Pose()
            rospy.wait_for_service("/" + tname + '/set_pen')
            try:
                client = rospy.ServiceProxy("/" + tname + '/set_pen', SetPen)
                client(0,0,0,0,1)
            except rospy.ServiceException as e:
                print("Service call failed: %s"%e)
        except rospy.ServiceException as e:
            print("Service tp spawn a turtle failed. %s", e)

    def turtle_poseCallback(self, data):
        self.turtle_pose = data

    def turtle_velocity(self, msg):
        self.pub.publish(msg)


def turtle1_poseCallback(data):
    global turtle1_pose
    global lastturtle
    global turtlelist
    global nextturtleIndex
    turtle1_pose.x = round(data.x, 4)
    turtle1_pose.y = round(data.y, 4)
    turtle1_pose.theta = round(data.theta, 4)

    for i in range(len(turtlelist)):
        twist_data = Twist()
        diff = math.sqrt(pow((turtle1_pose.x - turtlelist[i].turtle_pose.x) , 2) + pow((turtle1_pose.y - turtlelist[i].turtle_pose.y), 2))
        ang = math.atan2(turtle1_pose.y - turtlelist[i].turtle_pose.y, turtle1_pose.x - turtlelist[i].turtle_pose.x) - turtlelist[i].turtle_pose.theta

        if(ang <= -3.14) or (ang > 3.14):
            ang = ang / math.pi

        if (turtlelist[i].state == 1):
            if diff < 1.0:
                turtlelist[i].state = 2
                turtlelist[i].turtle_to_follow = lastturtle
                lastturtle = i + 2
                rospy.loginfo("turtle Changed [%s] [%f] [%f]", turtlelist[i].turtle_name, diff, ang)
                nextturtleIndex += 1
                turtlelist.append(mySpawner("turtle" + str(nextturtleIndex)))
        else:
            parPose = turtle1_pose
            if(turtlelist[i].turtle_to_follow != 1):
                parPose = turtlelist[turtlelist[i].turtle_to_follow - 2].turtle_pose

            diff = math.sqrt(pow((parPose.x - turtlelist[i].turtle_pose.x) , 2) + pow((parPose.y - turtlelist[i].turtle_pose.y), 2))
            goal = math.atan2(parPose.y - turtlelist[i].turtle_pose.y, parPose.x - turtlelist[i].turtle_pose.x)
            ang = math.atan2(math.sin(goal - turtlelist[i].turtle_pose.theta), math.cos(goal - turtlelist[i].turtle_pose.theta))

            if(ang <= -3.14) or (ang > 3.14):
                ang = ang / (2*math.pi)

            if(diff < 0.8):
                twist_data.linear.x = 0 
                twist_data.angular.z = 0
            else:
                twist_data.linear.x = 2.5 * diff                
                twist_data.angular.z = 20 * ang

            turtlelist[i].turtle_velocity(twist_data)
            turtlelist[i].oldAngle = ang    



def spawn_turtle_fn():
    global nextturtleIndex
    rospy.init_node('snake_turtle', anonymous=True)
    rospy.Subscriber('/turtle1/pose', Pose, turtle1_poseCallback)
    rospy.wait_for_service("/turtle1/set_pen")
    try:
        client = rospy.ServiceProxy('/turtle1/set_pen', SetPen)
        client(0,0,0,0,1)
    except rospy.ServiceException as e:
        print("Service call failed: %s"%e)

    nextturtleIndex += 1
    turtlelist.append(mySpawner("turtle" + str(nextturtleIndex)))
    # for i in range(2,10):
    #     turtlelist.append(mySpawner("turtle" + str(i)))

    rospy.spin()

if __name__ == "__main__":
    spawn_turtle_fn()

ROS机器人turtlesim是一个基于ROS的仿真器,它模拟了一个海龟在屏幕上移动的过程。它可以用于学习ROS的基本概念和编程技巧,如发布和订阅消息、控制机器人运动等。在turtlesim中,你可以通过键盘输入控制指令,让海龟向前、向后、左转、右转等。此外,turtlesim还提供了一些高级功能,如记录和回放机器人的运动轨迹、设置机器人的速度和角速度等。总之,turtlesim是一个非常有用的工具,可以帮助你更好地理解ROS和机器人控制。