Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

80 crptg1prioc stanley and pp implementation #82

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ logs/
build/
install/

.vscode/
.vscode/
35 changes: 35 additions & 0 deletions crp_APL/controllers/ctrl_vehicle_control_lat_pure_p/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 3.8)
project(ctrl_vehicle_control_lat_pure_p)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(std_msgs REQUIRED)
find_package(autoware_control_msgs REQUIRED)
find_package(autoware_planning_msgs REQUIRED)
find_package(autoware_vehicle_msgs REQUIRED)
find_package(nav_msgs REQUIRED)
find_package(pacmod3_msgs REQUIRED)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need pcamod3 at this stage?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true. not needed

find_package(crp_msgs REQUIRED)


include_directories(include)


add_executable(ctrl_vehicle_control_lat_pure_p src/ctrl_vehicle_control_lat_pure_p.cpp)

ament_target_dependencies(ctrl_vehicle_control_lat_pure_p rclcpp geometry_msgs std_msgs autoware_control_msgs autoware_planning_msgs autoware_vehicle_msgs nav_msgs pacmod3_msgs crp_msgs)

install(DIRECTORY launch
DESTINATION share/${PROJECT_NAME})

install(TARGETS
ctrl_vehicle_control_lat_pure_p
DESTINATION lib/${PROJECT_NAME})

ament_package()
27 changes: 27 additions & 0 deletions crp_APL/controllers/ctrl_vehicle_control_lat_pure_p/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Ctrl Vehicle Control

A package for trajectory following, Lateral and Longitudinal Control of the Vehicle in the APL layer.

## APL level Controller of the Vehicle

The Controller uses a PID controller, with a Feedback and FeedForward layer, the error in the Feedback loop is based on lateral and angle errror.

### Usage:

```
ros2 launch ctrl_vehicle_control ctrl_vehicle_control.launch.py
```

### Parameters
| Name | Type | Default value |
|------------------|--------|-------------------------------------------------|
| /ctrl/ffGainOffsetGround | double | 1.0 |
| /ctrl/ffGainSlope | double | 0.1 |
| /ctrl/ffLookAheadTime | double | 1.5
| /ctrl/steeringAngleLPFilter | double | 0.7
| /ctrl/fbLookAheadTime | double | 0.5
| /ctrl/fbPGain | double | 0.01
| /ctrl/fbDGain | double | 0.0
| /ctrl/fbIGain | double | 0.0
| /ctrl/fbMinLookAheadDistance | double | 0.0
| /ctrl/fbIntegralLimit | double | 3.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef CONTROLLER_INPUTS_HPP_
#define CONTROLLER_INPUTS_HPP_


#include <stdio.h>
#include <string>
#include <vector>


namespace crp
{
namespace apl
{
struct ControlInput{
std::vector<double> path_x;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use our way of noting m_ for member variables

Suggested change
std::vector<double> path_x;
std::vector<double> m_path_x;

std::vector<double> path_y;
std::vector<double> path_theta;
double target_speed{0.0f};
double egoPoseGlobal [3]{0.0f};
double vxEgo{0.0f};
double egoSteeringAngle{0.0f};
};

struct ControlParams{
double lookahead_time{1.0f};
double wheelbase{2.9f};
};
}
}

#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if this struct was never defined before... we are in crp::apl namespace, where ControlInputs/Output struct types may have been defined already... wouldn't this cause any troubles?
btw, for all controllers the same base class definition shall be done as we did for planners, right @AnonymDavid ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For controllers we don't have any interfaces defined yet. But yes it should have a base class and interfaces defined in crp_APL/interfaces. Should this be another task since the other controllers are missing these too?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ye, make it another task, pls @gfigneczi1

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef CONTROLLER_OUTPUTS_HPP_
#define CONTROLLER_OUTPUTS_HPP_

#include <stdio.h>
#include <string>
#include <vector>


namespace crp
{
namespace apl
{
struct ControlOutput{
double accelerationTarget{0.0f};
double steeringAngleTarget{0.0f};
};
}
}

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#ifndef CRP_APL_CTRL_VEHICLE_LAT_COMPENSATORY_HPP
#define CRP_APL_CTRL_VEHICLE_LAT_COMPENSATORY_HPP

#include <chrono>
#include <functional>
#include <memory>
#include <string>
#include <math.h>
#include "rclcpp/rclcpp.hpp"
#include "geometry_msgs/msg/pose.hpp"
#include "std_msgs/msg/float32_multi_array.hpp"
#include "std_msgs/msg/float32.hpp"
#include "crp_msgs/msg/ego.hpp"

#include "autoware_control_msgs/msg/control.hpp"
#include "autoware_planning_msgs/msg/trajectory.hpp"
#include "autoware_vehicle_msgs/msg/steering_report.hpp"

#include "ctrl_vehicle_control_lat_pure_p/controller_inputs.hpp"
#include "ctrl_vehicle_control_lat_pure_p/controller_outputs.hpp"

namespace crp
{
namespace apl
{
class CtrlVehicleControlLat : public rclcpp::Node
{
public:
CtrlVehicleControlLat();

private:
// VARIABLES
crp::apl::ControlInput m_input;
crp::apl::ControlOutput m_output;
crp::apl::ControlParams m_params;

void trajCallback(const autoware_planning_msgs::msg::Trajectory input_msg);
void egoVehicleCallback(const crp_msgs::msg::Ego input_msg);

void pure_p_control();
void loop();

rclcpp::TimerBase::SharedPtr timer_;
rclcpp::Publisher<autoware_control_msgs::msg::Lateral>::SharedPtr m_pub_cmd;

rclcpp::Subscription<autoware_planning_msgs::msg::Trajectory>::SharedPtr m_traj_sub_;
rclcpp::Subscription<crp_msgs::msg::Ego>::SharedPtr m_egoVehicle_sub_;
autoware_control_msgs::msg::Lateral m_ctrlCmdMsg;
};
} // namespace apl
}
#endif // CRP_APL_CTRL_VEHICLE_LAT_COMPENSATORY_HPP
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formality, but still...

Suggested change
#endif // CRP_APL_CTRL_VEHICLE_LAT_COMPENSATORY_HPP
#endif // CRP_APL_CTRL_VEHICLE_LAT_PURE_P_HPP

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
ld = LaunchDescription()

ctrl_vehicle_control_lat_pure_p = Node(
package="ctrl_vehicle_control_lat_pure_p",
executable="ctrl_vehicle_control_lat_pure_p",
parameters=[
{"/ctrl/lookahead_time": 1.0},
{"/ctrl/wheelbase": 2.7},
]
)

ld.add_action(ctrl_vehicle_control_lat_pure_p)

return ld
29 changes: 29 additions & 0 deletions crp_APL/controllers/ctrl_vehicle_control_lat_pure_p/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>ctrl_vehicle_control_lat_pure_p</name>
<version>0.0.0</version>
<description>Vehicle Control Package with Stanley lateral controller</description>
<maintainer email="[email protected]">mesmatyi</maintainer>
<license>Apache License 2.0</license>

<buildtool_depend>ament_cmake</buildtool_depend>

<exec_depend>ros2launch</exec_depend>

<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<depend>rclcpp</depend>
<depend>geometry_msgs</depend>
<depend>std_msgs</depend>
<depend>autoware_control_msgs</depend>
<depend>autoware_planning_msgs</depend>
<depend>autoware_vehicle_msgs</depend>
<depend>nav_msgs</depend>
<depend>pacmod3_msgs</depend>
<depend>crp_msgs</depend>

<export>
<build_type>ament_cmake</build_type>
</export>
</package>
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#include <ctrl_vehicle_control_lat_pure_p/ctrl_vehicle_control_lat_pure_p.hpp>

using namespace std::chrono_literals;
using std::placeholders::_1;


crp::apl::CtrlVehicleControlLat::CtrlVehicleControlLat() : Node("CtrlVehicleControlLatPurePursuit")
{
timer_ = this->create_wall_timer(std::chrono::milliseconds(33), std::bind(&CtrlVehicleControlLat::loop, this));
m_pub_cmd = this->create_publisher<autoware_control_msgs::msg::Lateral>("/control/command/control_cmdLat", 30);

m_traj_sub_ = this->create_subscription<autoware_planning_msgs::msg::Trajectory>("/plan/trajectory", 10, std::bind(&CtrlVehicleControlLat::trajCallback, this, std::placeholders::_1));
m_egoVehicle_sub_ = this->create_subscription<crp_msgs::msg::Ego>("/ego", 10, std::bind(&CtrlVehicleControlLat::egoVehicleCallback, this, std::placeholders::_1));

this->declare_parameter("/ctrl/lookahead_time", 1.0f);
this->declare_parameter("/ctrl/wheelbase", 2.7f);

RCLCPP_INFO(this->get_logger(), "ctrl_vehicle_control has been started");
}

void crp::apl::CtrlVehicleControlLat::trajCallback(const autoware_planning_msgs::msg::Trajectory input_msg)
{
m_input.path_x.clear();
m_input.path_y.clear();
m_input.path_theta.clear();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

path theta is not filled up, shall we do it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deteled the clear part, but also not really needed

double quaternion[4];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

either you forgot to assign the orientation or quaternion variable is not needed



// this callback maps the input trajectory to the internal interface
for (long unsigned int i=0; i<input_msg.points.size(); i++)
{
m_input.path_x.push_back(input_msg.points.at(i).pose.position.x);
m_input.path_y.push_back(input_msg.points.at(i).pose.position.y);
}

if (input_msg.points.size() > 0)
m_input.target_speed = input_msg.points.at(0).longitudinal_velocity_mps;
else
m_input.target_speed = 0.0f;

}

void crp::apl::CtrlVehicleControlLat::egoVehicleCallback(const crp_msgs::msg::Ego input_msg)
{
m_input.vxEgo = input_msg.twist.twist.linear.x;
m_input.egoSteeringAngle = input_msg.tire_angle_front;

m_input.egoPoseGlobal[0] = input_msg.pose.pose.position.x;
m_input.egoPoseGlobal[1] = input_msg.pose.pose.position.y;
}

void crp::apl::CtrlVehicleControlLat::pure_p_control()
{

float distance_to_index = m_input.vxEgo * m_params.lookahead_time;

RCLCPP_INFO(this->get_logger(), "distance to index: %f", distance_to_index);

float current_distance = 0.0f;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formality (again) but I think we agreed on using camelCase for all internal variables...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deleted, dont feel its need thoug

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't get this, it is still not camel case

int target_index = 0;

for (int i = 0; i < m_input.path_x.size()-1; i++)
{
current_distance += sqrt(pow(m_input.path_x.at(i+1) - m_input.path_x.at(i), 2) + pow(m_input.path_y.at(i+1) - m_input.path_y.at(i), 2));
if (current_distance > distance_to_index)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

greater or equal?

{
target_index = i;
break;
}
}

// calculate the steering angle
m_output.steeringAngleTarget = 0.0f;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need this row?


float alpha = atan2(m_input.path_y[target_index], m_input.path_x[target_index]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

target_index shall be checked, if greater than zero (if trajectory is too small, or the look ahead distance is too high, than it remains 0 per line 60... probably it shall be set to last point by default? supposing the path contains any points


m_output.steeringAngleTarget = atan2(2.0f * m_params.wheelbase * sin(alpha) / distance_to_index, 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simple atan?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If ego speed (m_input.vxEgo) is 0 than distance_to_index would be 0 too and this would give a zero division error, no? In that case there should be a check for that.


}

void crp::apl::CtrlVehicleControlLat::loop()
{
// parameter assignments
m_params.lookahead_time = this->get_parameter("/ctrl/lookahead_time").as_double();
m_params.wheelbase = this->get_parameter("/ctrl/wheelbase").as_double();

// control algorithm
if(m_input.path_x.size() > 0 && m_input.path_y.size() > 0)
pure_p_control();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else zero steering angle target? otherwise system keeps the last value which is not the safe behavior

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else i would just drop the msg (not publish anything), for ex. when the steering wheel is at 20 deg and all of a sudden comes back 0, is not the best behavior in my op...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i dont like the idea of the message being dropped, as then we cannot ensure the safe state. Having zero steering angle AND some kind of deactivation logic (which will be implemented later I guess) together would be the best. Going back from one value to another smoothly is the responsibility of the jerk and acceleration limits of what @AnonymDavid is working on right now, so that will not be a problem.


// steering angle and steering angle gradiant
m_ctrlCmdMsg.stamp = this->now();
m_ctrlCmdMsg.steering_tire_angle = m_output.steeringAngleTarget;
m_ctrlCmdMsg.steering_tire_rotation_rate = 0.0f;

m_pub_cmd->publish(m_ctrlCmdMsg);
}


int main(int argc, char *argv[])
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<crp::apl::CtrlVehicleControlLat>());
rclcpp::shutdown();
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 3.8)
project(ctrl_vehicle_control_lat_stanley)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(std_msgs REQUIRED)
find_package(autoware_control_msgs REQUIRED)
find_package(autoware_planning_msgs REQUIRED)
find_package(autoware_vehicle_msgs REQUIRED)
find_package(nav_msgs REQUIRED)
find_package(pacmod3_msgs REQUIRED)
find_package(crp_msgs REQUIRED)


include_directories(include)


add_executable(ctrl_vehicle_control_lat_stanley src/ctrl_vehicle_control_lat_stanley.cpp)

ament_target_dependencies(ctrl_vehicle_control_lat_stanley rclcpp geometry_msgs std_msgs autoware_control_msgs autoware_planning_msgs autoware_vehicle_msgs nav_msgs pacmod3_msgs crp_msgs)

install(DIRECTORY launch
DESTINATION share/${PROJECT_NAME})

install(TARGETS
ctrl_vehicle_control_lat_stanley
DESTINATION lib/${PROJECT_NAME})

ament_package()
Loading
Loading