Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
Firmware
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Alberto Ruiz Garcia
Firmware
Commits
81da94ff
Commit
81da94ff
authored
7 years ago
by
Dennis Mannhart
Committed by
Beat Küng
6 years ago
Browse files
Options
Downloads
Patches
Plain Diff
PositionControl: Anti-windup that uses max in NE based on tilt limit and remaining throttle
excess
parent
f99471f3
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/modules/mc_pos_control/PositionControl.cpp
+77
-42
77 additions, 42 deletions
src/modules/mc_pos_control/PositionControl.cpp
src/modules/mc_pos_control/PositionControl.hpp
+10
-2
10 additions, 2 deletions
src/modules/mc_pos_control/PositionControl.hpp
with
87 additions
and
44 deletions
src/modules/mc_pos_control/PositionControl.cpp
+
77
−
42
View file @
81da94ff
...
...
@@ -183,7 +183,8 @@ void PositionControl::_positionController()
_vel_sp
(
1
)
=
_vel_sp
(
1
)
*
_VelMaxXY
/
vel_norm_xy
;
}
_vel_sp
(
2
)
=
math
::
constrain
(
_vel_sp
(
2
),
-
_VelMaxZ
[
0
],
_VelMaxZ
[
1
]);
/* Saturate velocity in D-direction */
_vel_sp
(
2
)
=
math
::
constrain
(
_vel_sp
(
2
),
-
_VelMaxZ
.
up
,
_VelMaxZ
.
down
);
}
void
PositionControl
::
_velocityController
(
const
float
&
dt
)
...
...
@@ -193,67 +194,101 @@ void PositionControl::_velocityController(const float &dt)
* u_des = P(vel_err) + D(vel_err_dot) + I(vel_integral)
* Umin <= u_des <= Umax
*
*
Saturation for vel_integral;
*
Anti-Windup:
* u_des = _thr_sp; r = _vel_sp; y = _vel
* u_des >= Umax and r - y >= 0 => Saturation = true
* u_des >= Umax and r - y <= 0 => Saturation = false
* u_des <= Umin and r - y <= 0 => Saturation = true
* u_des <= Umin and r - y >= 0 => Saturation = false
*
* Notes:
* - PID implementation is in NED-frame
* - control output in D-direction has priority over NE-direction
* - the equilibrium point for the PID is at hover-thrust
* - the maximum tilt cannot exceed 90 degrees. This means that it is
* not possible to have a desired thrust direction pointing in the positive
* D-direction (= downward)
* - the desired thrust in D-direction is limited by the thrust limits
* - the desired thrust in NE-direction is limited by the thrust excess after
* consideration of the desired thrust in D-direction. In addition, the thrust in
* NE-direction is also limited by the maximum tilt.
*/
/* Get maximum tilt */
float
tilt_max
=
M_PI_2_F
;
if
(
PX4_ISFINITE
(
_constraints
.
tilt_max
)
&&
_constraints
.
tilt_max
<=
tilt_max
)
{
tilt_max
=
_constraints
.
tilt_max
;
}
Vector3f
vel_err
=
_vel_sp
-
_vel
;
/* TODO: add offboard acceleration mode
* PID-controller */
Vector3f
offset
(
0.0
f
,
0.0
f
,
_ThrHover
);
Vector3f
thr_sp
=
Pv
.
emult
(
vel_err
)
+
Dv
.
emult
(
_vel_dot
)
+
_thr_int
-
offset
;
/*
* TODO: add offboard acceleration mode
* */
/* Get maximum tilt */
float
tilt_max
=
PX4_ISFINITE
(
_constraints
.
tilt_max
)
?
_constraints
.
tilt_max
:
M_PI_2_F
;
tilt_max
=
math
::
min
(
tilt_max
,
M_PI_2_F
);
/* Consider thrust in D-direction */
float
thrust_desired_D
=
Pv
(
2
)
*
vel_err
(
2
)
+
Dv
(
2
)
*
_vel_dot
(
2
)
+
_thr_int
(
2
)
-
_ThrHover
;
/* Compute maximum allowed thrust along xy based on thrust in z-direction and
* scale _thrust_sp by that value. This only has an effect for altitude mode where
* _thr_sp(0:1).length() > 0.0f.
*/
/* The Thrust limits are negated and swapped due to NED-frame */
float
uMax
=
-
_ThrustLimit
.
min
;
float
uMin
=
-
_ThrustLimit
.
max
;
/* Apply Anti-Windup in D-direction */
bool
stop_integral_D
=
(
thrust_desired_D
>=
uMax
&&
vel_err
(
2
)
>=
0.0
f
)
||
(
thrust_desired_D
<=
uMin
&&
vel_err
(
2
)
<=
0.0
f
);
if
(
!
stop_integral_D
)
{
_thr_int
(
2
)
+=
vel_err
(
2
)
*
Iv
(
2
)
*
dt
;
}
/* Satureate thrust setpoint in D-direction */
_thr_sp
(
2
)
=
math
::
constrain
(
thrust_desired_D
,
uMin
,
uMax
);
if
(
matrix
::
Vector2f
(
&
_thr_sp
(
0
)).
length
()
>
FLT_EPSILON
)
{
float
thr_xy_max
=
fabsf
(
thr_sp
(
2
))
*
tanf
(
tilt_max
);
/* Thrust setpoints in NE-direction is already provided. Only
* scaling is required.
*/
float
thr_xy_max
=
fabsf
(
_thr_sp
(
2
))
*
tanf
(
tilt_max
);
_thr_sp
(
0
)
*=
thr_xy_max
;
_thr_sp
(
1
)
*=
thr_xy_max
;
}
}
else
{
_thr_sp
+=
thr_sp
;
/* PID for NE-direction */
Vector2f
thrust_desired_NE
;
thrust_desired_NE
(
0
)
=
Pv
(
0
)
*
vel_err
(
0
)
+
Dv
(
0
)
*
_vel_dot
(
0
)
+
_thr_int
(
0
);
thrust_desired_NE
(
1
)
=
Pv
(
1
)
*
vel_err
(
1
)
+
Dv
(
1
)
*
_vel_dot
(
1
)
+
_thr_int
(
1
);
/*
Limit tilt with priority on z
* For manual controlled mode excluding pure manual and rate control, maximum tilt is 90
;
* It is to note that pure manual and rate control will never enter _velocityController method. */
_
thr
_sp
=
ControlMath
::
constrainT
ilt
(
_
thr
_sp
,
til
t_max
);
/*
Get maximum allowed thrust in NE based on tilt and excess thrust */
float
thrust_max_NE_tilt
=
fabsf
(
_thr_sp
(
2
))
*
tanf
(
tilt_max
)
;
float
thrust_max_NE
=
sqrtf
(
_ThrustLimit
.
max
*
_ThrustLimit
.
max
-
fabsf
(
_thr_sp
(
2
)
*
fabsf
(
_thr_sp
(
2
))));
thr
ust_max_NE
=
math
::
min
(
thrust_max_NE_t
ilt
,
thr
us
t_max
_NE
);
/* Get the direction of (r-y) in NE-direction */
float
direction_NE
=
Vector2f
(
&
vel_err
(
0
))
*
Vector2f
(
&
_vel_sp
(
0
));
/* Constrain thrust set-point and update saturation flag */
/* To get (r-y) for horizontal direction, we look at the dot-product
* for vel_err and _vel_sp. The sign of the dot product indicates
* if (r-y) is greater or smaller than 0
*/
float
dot_xy
=
matrix
::
Vector2f
(
&
_vel_sp
(
0
))
*
matrix
::
Vector2f
(
&
_vel
(
0
));
float
direction
[
2
]
=
{
dot_xy
,
-
vel_err
(
2
)};
// negative sign because of N-E-D
bool
stop_I
[
2
]
=
{
false
,
false
};
// stop integration for xy and z
ControlMath
::
constrainPIDu
(
_thr_sp
,
stop_I
,
_ThrLimit
,
direction
);
/* Update integrals */
if
(
!
stop_I
[
0
])
{
_thr_int
(
0
)
+=
vel_err
(
0
)
*
Iv
(
0
)
*
dt
;
_thr_int
(
1
)
+=
vel_err
(
1
)
*
Iv
(
1
)
*
dt
;
}
/* Apply Anti-Windup in NE-direction */
bool
stop_integral_NE
=
(
thrust_desired_NE
.
length
()
>=
thrust_max_NE
&&
direction_NE
>=
0.0
f
);
if
(
!
stop_I
[
1
])
{
_thr_int
(
2
)
+=
vel_err
(
2
)
*
Iv
(
2
)
*
dt
;
}
if
(
!
stop_integral_NE
)
{
_thr_int
(
0
)
+=
vel_err
(
0
)
*
Iv
(
0
)
*
dt
;
_thr_int
(
1
)
+=
vel_err
(
1
)
*
Iv
(
1
)
*
dt
;
}
/* Saturate thrust in NE-direction */
_thr_sp
(
0
)
=
thrust_desired_NE
(
0
);
_thr_sp
(
1
)
=
thrust_desired_NE
(
1
);
if
(
thrust_desired_NE
.
length
()
>
thrust_max_NE
)
{
_thr_sp
(
0
)
=
thrust_desired_NE
(
0
)
/
thrust_desired_NE
.
length
()
*
thrust_max_NE
;
_thr_sp
(
1
)
=
thrust_desired_NE
(
1
)
/
thrust_desired_NE
.
length
()
*
thrust_max_NE
;
}
}
}
...
...
@@ -293,10 +328,10 @@ void PositionControl::_setParams()
param_get
(
_Dvz_h
,
&
Dv
(
2
));
param_get
(
_VelMaxXY_h
,
&
_VelMaxXY
);
param_get
(
_VelMaxZup_h
,
&
_VelMaxZ
[
0
]
);
param_get
(
_VelMaxZdown_h
,
&
_VelMaxZ
[
1
]
);
param_get
(
_VelMaxZup_h
,
&
_VelMaxZ
.
up
);
param_get
(
_VelMaxZdown_h
,
&
_VelMaxZ
.
down
);
param_get
(
_ThrHover_h
,
&
_ThrHover
);
param_get
(
_ThrMax_h
,
&
_ThrLimit
[
0
]
);
param_get
(
_ThrMin_h
,
&
_ThrLimit
[
1
]
);
param_get
(
_ThrMax_h
,
&
_Thr
ust
Limit
.
max
);
param_get
(
_ThrMin_h
,
&
_Thr
ust
Limit
.
min
);
}
This diff is collapsed.
Click to expand it.
src/modules/mc_pos_control/PositionControl.hpp
+
10
−
2
View file @
81da94ff
...
...
@@ -116,9 +116,17 @@ private:
/* Parameters */
matrix
::
Vector3f
Pp
,
Pv
,
Iv
,
Dv
=
matrix
::
Vector3f
{
0.0
f
,
0.0
f
,
0.0
f
};
float
_VelMaxXY
{};
float
_VelMaxZ
[
2
];
//index 0: index up; 1: down
struct
DirectionD
{
float
up
;
float
down
;
};
DirectionD
_VelMaxZ
;
struct
Limits
{
float
max
;
float
min
;
};
Limits
_ThrustLimit
;
float
_ThrHover
{
0.5
f
};
float
_ThrLimit
[
2
];
//index 0: max, index 1: min
bool
_skipController
{
false
};
/* Helper methods */
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment