## Node
execution unit, it mainly function is calculating, controling or connecting to other nodes.
>[!Warning] it is a temporary storage place
### python
#### 1. once
- hello.py
```python=
from rclpy import init, create_node, spin, shutdown
def main(args=None): #introduce arguments
rclpy.init(args=args)
node = create_node("HELLO") #create a node HELLO
node.get_logger().info("Hello, World!!!") # print
spin(node) # run once
shutdown()
if __name__ == '__main__':
main()
```
#### 2. loop
- hello.py
```python=
from rclpy import init, spin_once, shutdown
def main(args=None): #introduce arguments
init(args=args)
node = rclpy.create_node("HELLO") #create a node HELLO
rate = node.create_rate(1) # set rate 1Hz
while rclpy.ok(): # rclpy nor interrupt
node.get_logger().info("Hello, World!!!") # print
spin_once(node) # run once
shutdown()
if __name__ == '__main__':
main()
```
- package.xml
```xml=
...
<exec_depend>rclpy</exec_depend>
...
```
### C++
#### 1. once
- hello.cpp
```cpp=
#include "rclcpp/rclcpp.hpp"
int main(int argc, char** argv){
rclcpp::init(argc, argv);
auto node = rclcpp::Node::make_shared("HELLO");
RCLCPP_INFO(node->get_logger(), "Hello, World!!!");
rclcpp::spin(node)
rclcpp::shutdown();
return 0;
}
```
#### 2. loop
- ROS
```cpp=
#include "rclcpp/rclcpp.hpp"
int main(int argc, char ** argv){
rclcpp::init(argc, argv);
auto node = rclcpp::Node::make_shared("HELLO");
rclcpp::WallRate loop_rate(1);
while (rclcpp::ok()){
rclcpp::spin_some(node);
RCLCPP_INFO(node->get_logger(), "Hello, World!!!");
loop_rate.sleep();
}
rclcpp::shutdown();
return 0;
}
```
- ROS2 - 1
```cpp=
#include "rclcpp/rclcpp.hpp"
// #include <chrono>
using namespace std;
int main(int argc, char ** argv){
rclcpp::init(argc, argv);
auto node = rclcpp::Node::make_shared("HELLO");
auto timer = node->create_wall_timer(
1s, //chrono::seconds(1);
[node]() -> void{RCLCPP_INFO(node->get_logger(), "Hello, World!!!");}
);
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
```
- ROS2 - 2
```cpp=
#include "rclcpp/rclcpp.hpp"
// #include <chrono>
using namespace std;
void callback(rclcpp::Node::SharedPtr node) {
RCLCPP_INFO(node->get_logger(), "Hello World in Loop!");
}
int main(int argc, char ** argv){
rclcpp::init(argc, argv);
auto node = rclcpp::Node::make_shared("HELLO");
auto timer = node->create_wall_timer(
1s, //chrono::seconds(1);
bind(&callback, node) //zero function --> callback(node)
);
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
```
> [!Tip] Zero function
calling function can't use paraments
## Node Attribute - Parameter
- intro
1. it's not a message stream
2. it can use CLI to operate
> [!Warning] Parameter
> When you want to run parameter, needing to run Node first.
### Python
```python=
from rclpy import init, spin
from rclpy.node import Node
from rclpy.parameter import Parameter
class Para(Node):
def __init__(self):
super().__init__('param_node')
self.declare_parameter('my_param', 'world') # create a parameter
self.timer = self.create_timer(1, self.callback)
def callback(self):
my_param = self.get_parameter('my_param').get_parameter_value().string_value
self.get_logger().info(f'Hello, {my_param}') # get parameter value and data-type change to string
new_my_param = Parameter(
'my_param', #parameter name
Parameter.Type.STRING, #parameter type
'world' #parameter value
)
self.set_parameters([new_my_param]) # update parameter
def main():
init()
spin( Para() )
if __name__ == '__main__':
main()
```
> `declare_parameter`
> `get_parameter_value`
> `set_parameters`: 記得加***s***
- setup.py
```python=
entry_points={
'console_scripts': [
'param_node = py_param.node:main'
],
},
```
### Cpp
```cpp=
#include <rclcpp/rclcpp.hpp>
#include <chrono>
#include <string>
#include <vector>
using namespace std::chrono_literals;
using rclcpp::Node;
using rclcpp::init;
using rclcpp::spin;
using rclcpp::Parameter;
using rclcpp::TimerBase;
using rclcpp::shutdown;
using std::string;
using std::vector;
using std::make_shared;
class Para: public Node {
public:
Para(): Node("para_node") {
this->declare_parameter("my_para", "world");
timer_= this->create_wall_timer(
1s,
[this](){
string my_para = this->get_parameter("my_para").as_string();
RCLCPP_INFO(this->get_logger(), "Hello, %s!", my_para.c_str());
vector<Parameter> all_para{Parameter("my_para", "world")};
this->set_parameters(all_para);
});
}
private:
TimerBase::SharedPtr timer_;
};
int main(int args, char** argv){
init(args, argv);
spin( make_shared<Para>() );
shutdown();
}
```
- CMakeLists.txt
```txt=
add_executable(para_node src/node.cpp)
ament_target_dependencies(para_node rclcpp)
install(TARGETS
para_node
DESTINATION lib/${PROJECT_NAME}
)
```
### Linux
```bash=
ros2 param set <node_name> <para_name> <changed_value>
```
### Parameter Function - launch