Skip to content

Commit

Permalink
Merge pull request #514 from tier4/sync-upstream
Browse files Browse the repository at this point in the history
chore: sync upstream
  • Loading branch information
tier4-autoware-public-bot[bot] authored May 24, 2023
2 parents 6787e23 + 2dc28a1 commit ecaaabc
Show file tree
Hide file tree
Showing 34 changed files with 830 additions and 587 deletions.
3 changes: 3 additions & 0 deletions common/signal_processing/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<version>0.1.0</version>
<description>The signal processing package</description>
<maintainer email="takayuki.murooka@tier4.jp">Takayuki Murooka</maintainer>
<maintainer email="takamasa.horibe@tier4.jp">Takamasa Horibe</maintainer>
<maintainer email="fumiya.watanabe@tier4.jp">Fumiya Watanabe</maintainer>
<maintainer email="kyoichi.sugahara@tier4.jp">Kyoichi Sugahara</maintainer>
<maintainer email="ali.boyali@tier4.jp">Ali Boyali</maintainer>

<license>Apache License 2.0</license>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ using autoware_auto_control_msgs::msg::AckermannControlCommand;
using autoware_auto_planning_msgs::msg::Trajectory;
using autoware_auto_vehicle_msgs::msg::SteeringReport;
using control_performance_analysis::msg::DrivingMonitorStamped;
using control_performance_analysis::msg::Error;
using control_performance_analysis::msg::ErrorStamped;
using control_performance_analysis::msg::FloatStamped;
using geometry_msgs::msg::Pose;
Expand Down Expand Up @@ -78,7 +79,7 @@ class ControlPerformanceAnalysisCore
void setOdomHistory(const Odometry & odom);
void setSteeringStatus(const SteeringReport & steering);

void findCurveRefIdx();
boost::optional<int32_t> findCurveRefIdx();
std::pair<bool, int32_t> findClosestPrevWayPointIdx_path_direction();
double estimateCurvature();
double estimatePurePursuitCurvature();
Expand All @@ -99,8 +100,6 @@ class ControlPerformanceAnalysisCore

// Variables Received Outside
std::shared_ptr<autoware_auto_planning_msgs::msg::Trajectory> current_trajectory_ptr_;
std::shared_ptr<PoseArray> current_waypoints_ptr_;
std::shared_ptr<std::vector<double>> current_waypoints_vel_ptr_;
std::shared_ptr<Pose> current_vec_pose_ptr_;
std::shared_ptr<std::vector<Odometry>> odom_history_ptr_; // velocities at k-2, k-1, k, k+1
std::shared_ptr<AckermannControlCommand> current_control_ptr_;
Expand All @@ -113,9 +112,8 @@ class ControlPerformanceAnalysisCore

// Variables computed

std::unique_ptr<int32_t> idx_prev_wp_; // the waypoint index, vehicle
std::unique_ptr<int32_t> idx_curve_ref_wp_; // index of waypoint corresponds to front axle center
std::unique_ptr<int32_t> idx_next_wp_; // the next waypoint index, vehicle heading to
std::unique_ptr<int32_t> idx_prev_wp_; // the waypoint index, vehicle
std::unique_ptr<int32_t> idx_next_wp_; // the next waypoint index, vehicle heading to
std::unique_ptr<ErrorStamped> prev_target_vars_{};
std::unique_ptr<DrivingMonitorStamped> prev_driving_vars_{};
std::shared_ptr<Pose> interpolated_pose_ptr_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ class ControlPerformanceAnalysisNode : public rclcpp::Node
rclcpp::Subscription<Odometry>::SharedPtr sub_velocity_; // subscribe to velocity
rclcpp::Subscription<SteeringReport>::SharedPtr sub_vehicle_steering_;

// Self Pose listener.
tier4_autoware_utils::SelfPoseListener self_pose_listener_{this}; // subscribe to pose listener.

// Publishers
rclcpp::Publisher<ErrorStamped>::SharedPtr pub_error_msg_; // publish error message
rclcpp::Publisher<DrivingMonitorStamped>::SharedPtr
Expand All @@ -78,7 +75,7 @@ class ControlPerformanceAnalysisNode : public rclcpp::Node
// Parameters
Params param_{}; // wheelbase, control period and feedback coefficients.
// State holder
std_msgs::msg::Header last_control_cmd_;
AckermannControlCommand::ConstSharedPtr last_control_cmd_;
double d_control_cmd_{0};

// Subscriber Parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
#include <Eigen/Geometry>
#include <rclcpp/rclcpp.hpp>

#include <geometry_msgs/msg/point.hpp>
#include <geometry_msgs/msg/quaternion.hpp>

#include <tf2/utils.h>

#include <cmath>
#include <utility>
#include <vector>

namespace control_performance_analysis
Expand All @@ -41,52 +43,20 @@ inline std::vector<double> getNormalVector(double yaw_angle)
return std::vector<double>{-sin(yaw_angle), cos(yaw_angle)};
}

inline std::vector<double> computeLateralLongitudinalError(
const std::vector<double> & closest_point_position, const std::vector<double> & vehicle_position,
const double & desired_yaw_angle)
inline std::pair<double, double> computeLateralLongitudinalError(
const geometry_msgs::msg::Point & closest_point_position,
const geometry_msgs::msg::Point & vehicle_position, const double & desired_yaw_angle)
{
// Vector to path point originating from the vehicle r - rd
std::vector<double> vector_to_path_point{
vehicle_position[0] - closest_point_position[0],
vehicle_position[1] - closest_point_position[1]};
vehicle_position.x - closest_point_position.x, vehicle_position.y - closest_point_position.y};

double lateral_error = -sin(desired_yaw_angle) * vector_to_path_point[0] +
cos(desired_yaw_angle) * vector_to_path_point[1];
double longitudinal_error = cos(desired_yaw_angle) * vector_to_path_point[0] +
sin(desired_yaw_angle) * vector_to_path_point[1];

return std::vector<double>{lateral_error, longitudinal_error};
}

inline double computeLateralError(
std::vector<double> & closest_point_position, std::vector<double> & vehicle_position,
double & yaw_angle)
{
// Normal vector of vehicle direction
std::vector<double> normal_vector = getNormalVector(yaw_angle);

// Vector to path point originating from the vehicle
std::vector<double> vector_to_path_point{
closest_point_position[0] - vehicle_position[0],
closest_point_position[1] - vehicle_position[1]};

double lateral_error =
normal_vector[0] * vector_to_path_point[0] + normal_vector[1] * vector_to_path_point[1];

return lateral_error;
}

/*
* Shortest distance between two angles. As the angles are cyclic, interpolation between to
* angles must be carried out using the distance value instead of using the end values of
* two points.
* */
inline double angleDistance(const double & target_angle, const double & reference_angle)
{
double diff = std::fmod(target_angle - reference_angle + M_PI_2, 2 * M_PI) - M_PI_2;
double diff_signed_correction = diff < -M_PI_2 ? diff + 2 * M_PI : diff; // Fix sign

return -1.0 * diff_signed_correction;
return {lateral_error, longitudinal_error};
}

inline geometry_msgs::msg::Quaternion createOrientationMsgFromYaw(double yaw_angle)
Expand Down
1 change: 1 addition & 0 deletions control/control_performance_analysis/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
<depend>tf2_eigen</depend>
<depend>tf2_ros</depend>
<depend>tier4_autoware_utils</depend>
<depend>tier4_debug_msgs</depend>
<depend>vehicle_info_util</depend>
<exec_depend>builtin_interfaces</exec_depend>
<exec_depend>global_parameter_loader</exec_depend>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#!/usr/bin/env python3

# Copyright 2023 Tier IV, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import argparse
import math

from control_performance_analysis.msg import DrivingMonitorStamped
from control_performance_analysis.msg import ErrorStamped
import matplotlib.pyplot as plt
from nav_msgs.msg import Odometry
import rclpy
from rclpy.node import Node
from tier4_debug_msgs.msg import BoolStamped

parser = argparse.ArgumentParser()
parser.add_argument("-i", "--interval", help="interval distance to plot")
parser.add_argument("-r", "--realtime_plot", default=True, help="Enable real-time plotting")


class PlotterNode(Node):
def __init__(self, realtime_plot):
super().__init__("plotter_node")

self.realtime_plot = realtime_plot

self.subscription_error = self.create_subscription(
ErrorStamped, "/control_performance/performance_vars", self.error_callback, 10
)
self.subscription_driving = self.create_subscription(
DrivingMonitorStamped, "driving_topic", self.driving_callback, 10
)
self.subscription_odometry = self.create_subscription(
Odometry, "/localization/kinematic_state", self.odometry_callback, 10
)
self.subscription_plot = self.create_subscription(
BoolStamped, "/make_plot", self.make_plot_callback, 10
)
self.curvature = None
self.velocity = None
self.lateral_error = None
self.pose_distance_threshold = (
0.2 # Define the pose distance threshold to trigger plot update
)
self.previous_pos = None

self.abs_curvature_arr = []
self.abs_velocity_arr = []
self.abs_lateral_error_arr = []

self.fig, self.ax = plt.subplots(3, 3, figsize=(12, 9))
self.velocities = [
(0.0, 3.0),
(3.0, 6.0),
(6.0, 9.0),
(9.0, 12.0),
(12.0, 15.0),
(15.0, 18.0),
(18.0, 21.0),
(21.0, 24.0),
(24.0, float("inf")),
]
plt.pause(0.1)

def error_callback(self, msg):
print("error_callback!")
self.lateral_error = msg.error.lateral_error
self.curvature = msg.error.curvature_estimate

def driving_callback(self, msg):
print("driving_callback!")

def make_plot_callback(self, msg):
if msg.data is True:
self.update_plot()

def odometry_callback(self, msg):
print("odometry_callback!")
current_pos = msg.pose.pose.position
self.velocity = msg.twist.twist.linear.x

if self.previous_pos is None:
self.previous_pos = current_pos
return

if self.curvature is None:
print("waiting curvature")
return
if self.velocity is None:
print("waiting velocity")
return
if self.lateral_error is None:
print("waiting lateral_error")
return

pose_distance = self.calculate_distance(self.previous_pos, current_pos)
print("pose_distance = ", pose_distance)
if pose_distance >= self.pose_distance_threshold:
print("update!")
self.abs_curvature_arr.append(abs(self.curvature))
self.abs_lateral_error_arr.append(abs(self.lateral_error))
self.abs_velocity_arr.append(abs(self.velocity))
if self.realtime_plot is True:
self.update_plot()
self.previous_pos = current_pos

def calculate_distance(self, pos1, pos2):
distance = math.sqrt((pos2.x - pos1.x) ** 2 + (pos2.y - pos1.y) ** 2)
return distance

# def update_plot(self):
# if self.curvature is not None and self.velocity is not None and self.lateral_error is not None:
# self.curvature_arr.append(self.curvature)
# self.lateral_error_arr.append(self.lateral_error)
# self.velocity_arr.append(self.velocity)
# self.ax.cla() # Clear the existing plot
# self.ax.scatter(self.curvature_arr, self.velocity_arr, self.lateral_error_arr)
# plt.pause(0.001)
# else:
# print("waiting data in update_data")

def update_plot(self):
for i, (vel_min, vel_max) in enumerate(self.velocities):
indices = [j for j, v in enumerate(self.abs_velocity_arr) if vel_min <= v <= vel_max]

if len(indices) > 0:
ax = self.ax[i // 3, i % 3]
ax.cla()
ax.scatter(
[self.abs_curvature_arr[j] for j in indices],
[self.abs_lateral_error_arr[j] for j in indices],
)
ax.set_xlabel("Curvature")
ax.set_ylabel("Lateral Error")
ax.set_title(f"Velocity: {vel_min} - {vel_max}")

plt.tight_layout()
plt.pause(0.1) # Pause to allow the plot to update


def main(args=None):
rclpy.init()

args = parser.parse_args(args)
realtime_plot = args.realtime_plot

plotter_node = PlotterNode(realtime_plot)
print("spin start!")
rclpy.spin(plotter_node)
print("spin end!")
plotter_node.destroy_node()
rclpy.shutdown()


if __name__ == "__main__":
main()
Loading

0 comments on commit ecaaabc

Please sign in to comment.