Skip to content

Commit 668c01e

Browse files
authored
Battery updates (#183)
* Recharge services and a few battery improvements. Signed-off-by: Carlos Aguero <[email protected]> * Use atomic_bool. Signed-off-by: Carlos Aguero <[email protected]> Co-authored-by: Carlos Aguero <[email protected]>
1 parent ffde437 commit 668c01e

File tree

3 files changed

+80
-50
lines changed

3 files changed

+80
-50
lines changed

examples/worlds/linear_battery_demo.sdf

+1-1
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@
523523
<resistance>0.07</resistance>
524524
<smooth_current_tau>2.0</smooth_current_tau>
525525
<enable_recharge>true</enable_recharge>
526-
<!-- charging I = c / t, discharging I = P / V,
526+
<!-- charging I = c / t, discharging I = P / V,
527527
charging I should be > discharging I -->
528528
<charging_time>3.0</charging_time>
529529
<soc_threshold>0.51</soc_threshold>

src/systems/battery_plugin/LinearBatteryPlugin.cc

+72-45
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,32 @@
1616
*/
1717

1818
#include <ignition/msgs/battery_state.pb.h>
19+
#include <ignition/msgs/boolean.pb.h>
1920

20-
#include <string>
21+
#include <atomic>
2122
#include <functional>
23+
#include <string>
2224

23-
#include <ignition/plugin/Register.hh>
24-
#include <ignition/transport/Node.hh>
25-
26-
#include <ignition/common/Util.hh>
2725
#include <ignition/common/Battery.hh>
2826
#include <ignition/common/Profiler.hh>
27+
#include <ignition/common/Util.hh>
28+
29+
#include <ignition/plugin/Register.hh>
30+
#include <ignition/transport/Node.hh>
2931

3032
#include <sdf/Element.hh>
3133
#include <sdf/Physics.hh>
3234
#include <sdf/Root.hh>
3335
#include <sdf/World.hh>
3436

35-
#include "ignition/gazebo/Model.hh"
3637
#include "ignition/gazebo/components/BatterySoC.hh"
37-
#include "ignition/gazebo/components/Name.hh"
38-
#include "ignition/gazebo/components/World.hh"
38+
#include "ignition/gazebo/components/Joint.hh"
3939
#include "ignition/gazebo/components/JointForceCmd.hh"
4040
#include "ignition/gazebo/components/JointVelocityCmd.hh"
41+
#include "ignition/gazebo/components/Name.hh"
4142
#include "ignition/gazebo/components/ParentEntity.hh"
42-
#include "ignition/gazebo/components/Joint.hh"
43+
#include "ignition/gazebo/components/World.hh"
44+
#include "ignition/gazebo/Model.hh"
4345

4446
#include "LinearBatteryPlugin.hh"
4547

@@ -56,6 +58,14 @@ class ignition::gazebo::systems::LinearBatteryPluginPrivate
5658
/// \return State of charge of the battery in range [0.0, 1.0].
5759
public: double StateOfCharge() const;
5860

61+
/// \brief Callback executed to start recharging.
62+
/// \param[in] _req This value should be true.
63+
public: void OnEnableRecharge(const ignition::msgs::Boolean &_req);
64+
65+
/// \brief Callback executed to stop recharging.
66+
/// \param[in] _req This value should be true.
67+
public: void OnDisableRecharge(const ignition::msgs::Boolean &_req);
68+
5969
/// \brief Name of model, only used for printing warning when battery drains.
6070
public: std::string modelName;
6171

@@ -102,14 +112,11 @@ class ignition::gazebo::systems::LinearBatteryPluginPrivate
102112
public: double soc{1.0};
103113

104114
/// \brief Recharge status
105-
public: bool startCharging{false};
115+
public: std::atomic_bool startCharging{false};
106116

107117
/// \brief Hours taken to fully charge battery
108118
public: double tCharge{0.0};
109119

110-
/// \brief SoC threshold for enabling recharge
111-
public: double socThreshold{0.0};
112-
113120
/// \brief Battery current for a historic time window
114121
public: std::deque<double> iList;
115122

@@ -204,26 +211,6 @@ void LinearBatteryPlugin::Configure(const Entity &_entity,
204211
if (_sdf->HasElement("smooth_current_tau"))
205212
this->dataPtr->tau = _sdf->Get<double>("smooth_current_tau");
206213

207-
if (_sdf->HasElement("enable_recharge"))
208-
{
209-
auto isCharging = _sdf->Get<bool>("enable_recharge");
210-
if (isCharging)
211-
{
212-
if (_sdf->HasElement("charging_time") &&
213-
_sdf->HasElement("soc_threshold"))
214-
{
215-
this->dataPtr->tCharge = _sdf->Get<double>("charging_time");
216-
this->dataPtr->socThreshold = _sdf->Get<double>("soc_threshold");
217-
}
218-
else
219-
{
220-
ignerr << "No <charging_time> or <soc_threshold> specified."
221-
"Both are required to enable recharge.\n";
222-
return;
223-
}
224-
}
225-
}
226-
227214
if (_sdf->HasElement("battery_name") && _sdf->HasElement("voltage"))
228215
{
229216
auto batteryName = _sdf->Get<std::string>("battery_name");
@@ -233,7 +220,7 @@ void LinearBatteryPlugin::Configure(const Entity &_entity,
233220
this->dataPtr->batteryEntity = _ecm.CreateEntity();
234221
// Initialize with initial voltage
235222
_ecm.CreateComponent(this->dataPtr->batteryEntity,
236-
components::BatterySoC(this->dataPtr->soc));
223+
components::BatterySoC(this->dataPtr->soc));
237224
_ecm.CreateComponent(this->dataPtr->batteryEntity, components::Name(
238225
batteryName));
239226
_ecm.SetParentEntity(this->dataPtr->batteryEntity, _entity);
@@ -252,6 +239,31 @@ void LinearBatteryPlugin::Configure(const Entity &_entity,
252239
return;
253240
}
254241

242+
if (_sdf->HasElement("enable_recharge"))
243+
{
244+
auto isCharging = _sdf->Get<bool>("enable_recharge");
245+
if (isCharging)
246+
{
247+
if (_sdf->HasElement("charging_time"))
248+
this->dataPtr->tCharge = _sdf->Get<double>("charging_time");
249+
else
250+
{
251+
ignerr << "No <charging_time> specified. "
252+
"Parameter required to enable recharge.\n";
253+
return;
254+
}
255+
std::string enableRechargeService = this->dataPtr->modelName +
256+
"/" + _sdf->Get<std::string>("battery_name") + "/recharge/start";
257+
std::string disableRechargeService = this->dataPtr->modelName +
258+
"/" + _sdf->Get<std::string>("battery_name") + "/recharge/stop";
259+
260+
this->dataPtr->node.Advertise(enableRechargeService,
261+
&LinearBatteryPluginPrivate::OnEnableRecharge, this->dataPtr.get());
262+
this->dataPtr->node.Advertise(disableRechargeService,
263+
&LinearBatteryPluginPrivate::OnDisableRecharge, this->dataPtr.get());
264+
}
265+
}
266+
255267
// Consumer-specific
256268
if (_sdf->HasElement("power_load"))
257269
{
@@ -307,12 +319,29 @@ double LinearBatteryPluginPrivate::StateOfCharge() const
307319
return this->soc;
308320
}
309321

322+
//////////////////////////////////////////////////
323+
void LinearBatteryPluginPrivate::OnEnableRecharge(
324+
const ignition::msgs::Boolean &/*_req*/)
325+
{
326+
igndbg << "Request for start charging received" << std::endl;
327+
this->startCharging = true;
328+
}
329+
330+
//////////////////////////////////////////////////
331+
void LinearBatteryPluginPrivate::OnDisableRecharge(
332+
const ignition::msgs::Boolean &/*_req*/)
333+
{
334+
igndbg << "Request for stop charging received" << std::endl;
335+
this->startCharging = false;
336+
}
337+
310338
//////////////////////////////////////////////////
311339
void LinearBatteryPlugin::PreUpdate(
312340
const ignition::gazebo::UpdateInfo &/*_info*/,
313341
ignition::gazebo::EntityComponentManager &_ecm)
314342
{
315343
IGN_PROFILE("LinearBatteryPlugin::PreUpdate");
344+
this->dataPtr->startDraining = false;
316345
// Start draining the battery if the robot has started moving
317346
if (!this->dataPtr->startDraining)
318347
{
@@ -370,7 +399,7 @@ void LinearBatteryPlugin::Update(const UpdateInfo &_info,
370399
if (_info.paused)
371400
return;
372401

373-
if (!this->dataPtr->startDraining)
402+
if (!this->dataPtr->startDraining && !this->dataPtr->startCharging)
374403
return;
375404

376405
// Find the time at which battery starts to drain
@@ -421,10 +450,14 @@ void LinearBatteryPlugin::PostUpdate(const UpdateInfo &_info,
421450
msg.set_charge(this->dataPtr->q);
422451
msg.set_capacity(this->dataPtr->c);
423452
msg.set_percentage(this->dataPtr->soc);
424-
if (this->dataPtr->startDraining)
453+
if (this->dataPtr->startCharging)
454+
msg.set_power_supply_status(msgs::BatteryState::CHARGING);
455+
else if (this->dataPtr->startDraining)
425456
msg.set_power_supply_status(msgs::BatteryState::DISCHARGING);
426-
else
457+
else if (this->dataPtr->StateOfCharge() > 0.9)
427458
msg.set_power_supply_status(msgs::BatteryState::FULL);
459+
else
460+
msg.set_power_supply_status(msgs::BatteryState::NOT_CHARGING);
428461
this->dataPtr->statePub.Publish(msg);
429462
}
430463

@@ -455,14 +488,8 @@ double LinearBatteryPlugin::OnUpdateVoltage(
455488
// compute charging current
456489
auto iCharge = this->dataPtr->c / this->dataPtr->tCharge;
457490

458-
// charging criteria
459-
if (this->dataPtr->StateOfCharge() < this->dataPtr->socThreshold)
460-
this->dataPtr->startCharging = true;
461-
if (this->dataPtr->StateOfCharge() >= 0.9)
462-
this->dataPtr->startCharging = false;
463-
464491
// add charging current to battery
465-
if (this->dataPtr->startCharging)
492+
if (this->dataPtr->startCharging && this->dataPtr->StateOfCharge() < 0.9)
466493
this->dataPtr->iraw -= iCharge;
467494

468495
this->dataPtr->ismooth = this->dataPtr->ismooth + k *
@@ -500,7 +527,7 @@ double LinearBatteryPlugin::OnUpdateVoltage(
500527
igndbg << "PowerLoads().size(): " << _battery->PowerLoads().size()
501528
<< std::endl;
502529
igndbg << "charging status: " << std::boolalpha
503-
<< this->dataPtr->startCharging << std::endl;
530+
<< this->dataPtr->startCharging << std::endl;
504531
igndbg << "charging current: " << iCharge << std::endl;
505532
igndbg << "voltage: " << voltage << std::endl;
506533
igndbg << "state of charge: " << this->dataPtr->StateOfCharge()

src/systems/battery_plugin/LinearBatteryPlugin.hh

+7-4
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,21 @@ namespace systems
4040
/// \brief A plugin for simulating battery usage
4141
///
4242
/// This system processes the following sdf parameters:
43-
/// <battery_name> name of the battery
44-
/// <voltage> Initial voltage of the battery
43+
/// <battery_name> name of the battery (required)
44+
/// <voltage> Initial voltage of the battery (required)
4545
/// <open_circuit_voltage_constant_coef> Voltage at full charge
4646
/// <open_circuit_voltage_linear_coef> Amount of voltage decrease when no
4747
/// charge
4848
/// <initial_charge> Initial charge of the battery
4949
/// <capacity> Total charge that the battery can hold
5050
/// <resistance> Internal resistance
5151
/// <smooth_current_tau> coefficient for smoothing current
52-
/// <power_load> power load on battery
52+
/// <power_load> power load on battery (required)
5353
/// <start_on_motion> if set to true, the battery will start draining
54-
/// only if the robot has started moving
54+
/// only if the robot has started moving
55+
/// <enable_recharge> If true, the battery can be recharged
56+
/// <charging_time> Hours taken to fully charge the battery.
57+
/// (Required if <enable_recharge> is set to true)
5558
class IGNITION_GAZEBO_VISIBLE LinearBatteryPlugin
5659
: public System,
5760
public ISystemConfigure,

0 commit comments

Comments
 (0)