Ejemplo n.º 1
0
def control_callback(event):
    
    # Actual control is done here. The 'event' is the rospy.Timer() duration period, can be used 
    # for trubleshooting. To test how often is executed use: $ rostopic hz /mallard/thruster_commands.
    
    global x0,y0,q0,x_goal,y_goal,q_goal,ed
    global time_elapsed,t_goal,t_goal_psi
    global t_ramp,psivel
    twist = Twist()


    #  Get forces in global frame using PD controller
    if(goals_received == True and joy_button_L1 == 0 and joy_button_R1 == 0):

        
        # new code - velocity ramp
        # get current time
        tn = rospy.Time.now()
        time_now = tn.secs + (tn.nsecs * 0.000000001)
        # time elapsed form the start of tracking the goal (equal to t_now in goal selector)
        time_elapsed = time_now - time_begin
        # get max velocities
        xvelmax = abs(kguseful.safe_div((x_goal-x0),t_goal))
        yvelmax = abs(kguseful.safe_div((y_goal-y0),t_goal))
        # get desired position,velocity and acceleration from velocity ramp
        x_des, x_vel_des, x_acc_des = kglocal.velramp(time_elapsed, xvelmax, x0, x_goal, t_ramp,name="x")
        y_des, y_vel_des, y_acc_des = kglocal.velramp(time_elapsed, yvelmax, y0, y_goal, t_ramp,name="y")
        # get desired angle:
        qdes = kglocal.despsi_fun(q_goal, t_goal_psi, q0, time_elapsed)
        psi_des = tft.euler_from_quaternion(qdes)[2] # Its a list: (roll,pitch,yaw)
        # psi_des = psides[2]
        psi_vel_des = kglocal.desvelpsi_fun(ed, t_goal_psi, time_elapsed,psivel)
        # end new code
        
        
        # PD control
        # x_global_ctrl   = control.proportional(x, x_goal, x_vel, x_vel_goal, param['kp'], param['kd'], param['lim'])
        # y_global_ctrl   = control.proportional(y, y_goal, y_vel, y_vel_goal, param['kp'], param['kd'], param['lim'])
        psi_global_ctrl = control.proportional_angle(psi, psi_des,psi_vel,psi_vel_des, param['kp_psi'], param['kd_psi'], param['lim_psi'])
        # PD body control
        # x_PD_body = math.cos(psi)*x_global_ctrl + math.sin(psi)*y_global_ctrl
        # y_PD_body =-math.sin(psi)*x_global_ctrl + math.cos(psi)*y_global_ctrl 

        
        # ----- Model control -----        
        ax = control.acc_ctrl(x, x_des, x_vel, x_vel_des,x_acc_des,param_model_x['kp'], param_model_x['kd'], param_model_x['lim'])
        ay = control.acc_ctrl(y, y_des, y_vel, y_vel_des,y_acc_des,param_model_y['kp'], param_model_y['kd'], param_model_y['lim'])
        # Model body control:
        # aqx = Rt * [ax,ay]t
        # vqx = Rt * [x_vel,y_vel]t
        aqx =  math.cos(psi)*ax + math.sin(psi)*ay
        aqy = -math.sin(psi)*ax + math.cos(psi)*ay
        vqx =  math.cos(psi)*x_vel + math.sin(psi)*y_vel
        vqy = -math.sin(psi)*x_vel + math.cos(psi)*y_vel
        # print("X-velocity: " + str(round(vqx,4)))
        x_body_model_ctrl = Mx*aqx + R1_x*vqx + R2_x*(vqx*abs(vqx))
        # x_body_model_ctrl = Mx*aqx + R2_x*(vqx*abs(vqx))
        y_body_model_ctrl = My*aqy + R1_y*vqy + R2_y*(vqy*abs(vqy))
        # y_body_model_ctrl = My*aqy + R2_y*(vqy*abs(vqy))

        # twist.angular.y = data.buttons[4]
        # vector forces scaled in body frame
        twist.linear.x   = x_body_model_ctrl
        # twist.linear.x  = x_PD_body
        twist.linear.y  = y_body_model_ctrl
        # twist.linear.y  = y_PD_body
        twist.angular.z = -psi_global_ctrl

        # Test uniformity of the timer 
        now = rospy.Time.now()
        # twist.angular.x = now.secs
        # twist.angular.y = now.nsecs
        
        # Publish forces to simulation (joint_state_publisher message)
        pub_velocity.publish(twist)

        # send [time,position,velocity,goal_position,goal_velocity,control input]
        array_data = [now.secs,now.nsecs,\
                      x,y,psi,x_vel,y_vel,psi_vel,\
                      x_des,y_des,psi_des,x_vel_des,y_vel_des,psi_vel_des,\
                      x_body_model_ctrl,y_body_model_ctrl,psi_global_ctrl]
                      
        data_to_send = Float64MultiArray(data = array_data)
        pub_data.publish(data_to_send)

        # goals_received, xdes,ydes,psides[2],\
            #  xveldes,yveldes,psiveldes,ax,ay]

    elif(joy_button_L1 == 1 or joy_button_R1 == 1):
        twist.linear.x = joy_x
        twist.linear.y = joy_y
        twist.angular.z = joy_z
        pub_velocity.publish(twist)   
    else:
        # ----- idle if no goals -----
        pub_velocity.publish(Twist())
def control_callback(event):
    
    # Actual control is done here. The 'event' is the rospy.Timer() duration period, can be used 
    # for trubleshooting. To test how often is executed use: $ rostopic hz /mallard/thruster_commands.
    global x0,y0,q0,x_goal,y_goal,q_goal,ed
    global time_elapsed,t_goal,t_goal_psi
    global t_ramp,psivel  
    twist = Twist()

    #  Get forces in global frame using PD controller
    if(goals_received == True and joy_button_L1 == 0 and joy_button_R1 == 0):
        
        # new code - velocity ramp
        # get current time
        tn = rospy.Time.now()
        time_now = tn.secs + (tn.nsecs * 0.000000001)
        # time elapsed form the start of tracking the goal (equal to t_now in goal selector)
        time_elapsed = time_now - time_begin
        # get max velocities
        xvelmax = abs(kguseful.safe_div((x_goal-x0),t_goal))
        yvelmax = abs(kguseful.safe_div((y_goal-y0),t_goal))
        # get desired position,velocity and acceleration from velocity ramp
        x_des, x_vel_des, x_acc_des = kglocal.velramp(time_elapsed, xvelmax, x0, x_goal, t_ramp,name="x")
        y_des, y_vel_des, y_acc_des = kglocal.velramp(time_elapsed, yvelmax, y0, y_goal, t_ramp,name="y")
        # get desired angle:
        qdes = kglocal.despsi_fun(q_goal, t_goal_psi, q0, time_elapsed)
        psi_des = tft.euler_from_quaternion(qdes)[2] # Its a list: (roll,pitch,yaw)
        psi_vel_des = kglocal.desvelpsi_fun(ed, t_goal_psi, time_elapsed,psivel)
        # end new code
         
        # PD global control
        x_global_ctrl   = control.proportional(x, x_goal, x_vel, x_vel_goal, param['kp'], param['kd'], param['lim'])
        y_global_ctrl   = control.proportional(y, y_goal, y_vel, y_vel_goal, param['kp'], param['kd'], param['lim'])
        psi_global_ctrl = control.proportional_angle(psi, psi_goal,psi_vel,psi_vel_goal, param['kp_psi'], param['kd_psi'], param['lim_psi'])
        # Convert to body coordiante
        x_PD_body = math.cos(psi)*x_global_ctrl + math.sin(psi)*y_global_ctrl
        y_PD_body =-math.sin(psi)*x_global_ctrl + math.cos(psi)*y_global_ctrl 

        # Publish to twist velocitycommand
        twist.linear.x  = x_PD_body
        twist.linear.y  = y_PD_body
        twist.angular.z = -psi_global_ctrl

        # Generate time instance
        now = rospy.Time.now()
        twist.angular.x = now.secs
        twist.angular.y = now.nsecs

        # Publish forces to simulation (joint_state_publisher message)
        pub_velocity.publish(twist)

        # send [time,position,velocity,goal_position,goal_velocity,control input]
        array_data = [now.secs,now.nsecs,\  
                      x,y,psi,x_vel,y_vel,psi_vel,\
                      x_des,y_des,psi_des,x_vel_des,y_vel_des,psi_vel_des,\
                      x_body_model_ctrl,y_body_model_ctrl,psi_global_ctrl]

        data_to_send = Float64MultiArray(data = array_data)
        pub_data.publish(data_to_send)

    elif(joy_button_L1 == 1 or joy_button_R1 == 1):
        twist.linear.x = joy_x
        twist.linear.y = joy_y
        twist.angular.z = joy_z
        pub_velocity.publish(twist)   
    else:
        # ----- idle if no goals -----
        pub_velocity.publish(Twist())
def control_callback(event):
    # rospy.Timer() callback trigered by Duration(event).
    # Actual control is done here. The 'event' is the rospy.Timer() duration period, can be used
    # for trubleshooting. To test how often is executed use: $ rostopic hz /mallard/thruster_commands.

    global thruster_1, thruster_2, thruster_3, thruster_4  # control forces
    twist = Twist()

    #  Get forces in global frame using PD controller
    if (goals_received == True and joy_button_L1 == 0 and joy_button_R1 == 0):
        # print("x_acc_goal: ",x_acc_goal)
        # print("y_acc_goal: ",y_acc_goal)

        # PD body control
        x_global_ctrl = control.proportional(x, x_goal, x_vel, x_vel_goal,
                                             param['kp'], param['kd'],
                                             param['lim'])
        y_global_ctrl = control.proportional(y, y_goal, y_vel, y_vel_goal,
                                             param['kp'], param['kd'],
                                             param['lim'])
        psi_global_ctrl = control.proportional_angle(psi, psi_goal, psi_vel,
                                                     psi_vel_goal,
                                                     param['kp_psi'],
                                                     param['kd_psi'],
                                                     param['lim_psi'])

        x_PD_body = math.cos(psi) * x_global_ctrl + math.sin(
            psi) * y_global_ctrl
        y_PD_body = -math.sin(psi) * x_global_ctrl + math.cos(
            psi) * y_global_ctrl

        # ----- Model control -----
        # ax = control.acc_ctrl(x, x_goal, x_vel, x_vel_goal,x_acc_goal,param_model_x['kp'], param_model_x['kd'], param_model_x['lim'])
        # ay = control.acc_ctrl(y, y_goal, y_vel, y_vel_goal,y_acc_goal,param_model_y['kp'], param_model_y['kd'], param_model_y['lim'])

        # convert into body frame:
        # aqx = Rt * [ax,ay]t
        # vqx = Rt * [x_vel,y_vel]t
        # aqx =  math.cos(psi)*ax + math.sin(psi)*ay
        # aqy = -math.sin(psi)*ax + math.cos(psi)*ay

        # vqx =  math.cos(psi)*x_vel + math.sin(psi)*y_vel
        # vqy = -math.sin(psi)*x_vel + math.cos(psi)*y_vel
        # print("X-velocity: " + str(round(vqx,4)))
        # x_body_model_ctrl = Mx*aqx + R1_x*vqx + R2_x*(vqx*abs(vqx))
        # x_body_model_ctrl = Mx*aqx + R2_x*(vqx*abs(vqx))
        # y_body_model_ctrl = My*aqy + R1_y*vqy + R2_y*(vqy*abs(vqy))
        # y_body_model_ctrl = My*aqy + R2_y*(vqy*abs(vqy))

        # twist.angular.y = data.buttons[4]

        # vector forces scaled in body frame
        # twist.linear.x   = x_body_model_ctrl
        twist.linear.x = x_PD_body
        # twist.linear.y  = y_body_model_ctrl
        twist.linear.y = y_PD_body
        twist.angular.z = -psi_global_ctrl

        # Test uniformity of the timer
        now = rospy.Time.now()
        twist.angular.x = now.secs
        twist.angular.y = now.nsecs

        # Publish forces to simulation (joint_state_publisher message)
        pub_velocity.publish(twist)

    elif (joy_button_L1 == 1 or joy_button_R1 == 1):
        twist.linear.x = joy_x
        twist.linear.y = joy_y
        twist.angular.z = joy_z
        pub_velocity.publish(twist)
    else:
        # ----- idle if no goals -----
        pub_velocity.publish(Twist())
Ejemplo n.º 4
0
def slam_callback(msg):
    global time_prev, x_prev, y_prev, psi_prev
    global thruster_1, thruster_2, thruster_3, thruster_4

    # ----- Goals recived? -----
    if (goals_received == False):
        thruster_1 = 0
        thruster_2 = 0
        thruster_3 = 0
        thruster_4 = 0
        pub_velocity.publish(thruster_ctrl_msg())
        print("No goals received, idle. ")
        # Turn off thrustrs and exit callback
        return

    # ----- Position and Velocity -----
    # Get current position, orientation and time:
    x = msg.pose.position.x
    y = msg.pose.position.y
    psi = tft.euler_from_quaternion([msg.pose.orientation.x,msg.pose.orientation.y,\
                                     msg.pose.orientation.z,msg.pose.orientation.w])[2]
    time = (msg.header.stamp.secs + msg.header.stamp.nsecs * 0.000000001)
    # Derive velocities from slam data:
    time_diff = time - time_prev
    x_vel = control.get_velocity(x, x_prev, time_diff)
    y_vel = control.get_velocity(y, y_prev, time_diff)
    psi_vel = control.get_velocity(psi, psi_prev, time_diff)

    # ----- Control -----
    #  Get forces in global frame using PD controller
    x_global_ctrl = control.proportional(x, x_goal, x_vel, x_vel_goal,
                                         param['kp'], param['kd'],
                                         param['lim'])
    y_global_ctrl = control.proportional(y, y_goal, y_vel, y_vel_goal,
                                         param['kp'], param['kd'],
                                         param['lim'])
    psi_global_ctrl = control.proportional_angle(psi, psi_goal, psi_vel,
                                                 psi_vel_goal, param['kp_psi'],
                                                 param['kd_psi'],
                                                 param['lim_psi'])
    # convert into body frame:
    x_body_ctrl = math.cos(psi) * x_global_ctrl + math.sin(psi) * y_global_ctrl
    y_body_ctrl = -math.sin(psi) * x_global_ctrl + math.cos(
        psi) * y_global_ctrl

    # ----- Simulation -----
    # vector forces scaled in body frame
    x_sim = (x_body_ctrl) * linear_scale
    y_sim = (y_body_ctrl) * linear_scale
    psi_sim = (-psi_global_ctrl) * angular_scale

    # thrust allocation
    thruster_1 = 0 + 0.5 * x_sim + a_sim * psi_sim
    thruster_2 = 0 + 0.5 * x_sim - a_sim * psi_sim
    thruster_3 = 0 - 0.5 * y_sim + b_sim * psi_sim
    thruster_4 = 0 - 0.5 * y_sim - b_sim * psi_sim
    # Publish forces to simulation (joint_state_publisher message)
    pub_velocity.publish(thruster_ctrl_msg())

    # ----- Next iteratioon -----
    # Before finishing, assign current values to previous ones
    time_prev = time
    x_prev = x
    y_prev = y
    psi_prev = psi