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

Update link margin analysis #364

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ is_receiver = 1
// frequency [MHz]
frequency_MHz = 8200.0

// bitrate [bps]
tx_bitrate_bps = 10000
Copy link
Member

Choose a reason for hiding this comment

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

[Q] bitrateはアンテナが決めるものではなく、その前段の送信機などで決めるものな気もするのですが、ここにこのパラメータを置くべきなのでしょうか?

Copy link
Member Author

Choose a reason for hiding this comment

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

送信機などで決めるのであれば,tx_output_Wfrequency_MHzもな気がしていて.どちらかに統一したかったです.

Copy link
Member

Choose a reason for hiding this comment

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

frequency_MHzはアンテナも関わってくる気がするので、ここで良いのではないでしょうか?
tx_output_Wはたしかにそうなので、送信機側に動かしても良いと思います。

Copy link
Member Author

Choose a reason for hiding this comment

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

frequency_MHzはアンテナも関わってくる気がするので、ここで良いのではないでしょうか? tx_output_Wはたしかにそうなので、送信機側に動かしても良いと思います。

それを行いますと,

tx_eirp_dBW_ = 10 * log10(tx_output_power_W_) + tx_parameters_.loss_feeder_dB_ + tx_parameters_.loss_pointing_dB_;

の箇所がうまくいかなくなってしまうので,tx_eirp_dBWを別の場所に移行しなければならないので,アンテナの方に押し込んだほうがいいと思います.

Copy link
Member

Choose a reason for hiding this comment

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

当初の設計からの問題ということですね。。。今の段階でひとまず動くようにしておく というのと、 より理想的な形に持っていく というのを両立するため、ひとまずここでは次のような対処にするというのはどうでしょう?

  • 現時点ではAntenna クラスにSetTxBitrateSetTxPowerなどの関数を準備して、これらの値を別の通信システムから設定できるようにしておく
  • 理想的な状態への改修に向けてTODOやFIXMEでコメントつけておく、issueも立てる

Copy link
Member Author

Choose a reason for hiding this comment

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

  • 現時点ではAntenna クラスにSetTxBitrateやSetTxPowerなどの関数を準備して、これらの値を別の通信システムから設定できるようにしておく
  • 理想的な状態への改修に向けてTODOやFIXMEでコメントつけておく、issueも立てる

これに関してですが,現状送受信機のClassが存在していないので,とりあえずアンテナに帰属させるのがいいと思ったので,そのままにしています.GroundStationCalculatorにあるのも変なので.
そのうえで,FIXMEを切っておきました。

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Set関数を準備するというのは、「そのパラメータはひとまずアンテナに帰属するが、別のコンポが制御できるような余地を残しておく」という意図です。
Set関数を使わなかった時に使われるパラメータ初期値は今のような設定で良いので、動作としては今と特に変わらないかなと思います。

Copy link
Member

Choose a reason for hiding this comment

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

とはいえ、Setは後から追加でも良い気もしてきましたし、issueも切ってくれたのでapproveしておきます

Copy link
Member Author

Choose a reason for hiding this comment

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

ありがとうございます。
では、マージします


// Parameters for transmitter
// RF output power [W]
tx_output_W = 1.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ is_receiver = 1
// frequency [MHz]
frequency_MHz = 8200.0

// bitrate [bps]
tx_bitrate_bps = 100000

// Parameters for transmitter
// RF output power [W]
tx_output_W = 1.0
Expand Down
10 changes: 6 additions & 4 deletions src/components/real/communication/antenna.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <library/utilities/macros.hpp>

Antenna::Antenna(const int component_id, const libra::Quaternion& quaternion_b2c, const bool is_transmitter, const bool is_receiver,
const double frequency_MHz, const Vector<4> tx_parameters, const Vector<4> rx_parameters)
const double frequency_MHz, const Vector<5> tx_parameters, const Vector<4> rx_parameters)
: component_id_(component_id), is_transmitter_(is_transmitter), is_receiver_(is_receiver), frequency_MHz_(frequency_MHz) {
quaternion_b2c_ = quaternion_b2c;

Expand All @@ -18,6 +18,7 @@ Antenna::Antenna(const int component_id, const libra::Quaternion& quaternion_b2c
tx_parameters_.gain_dBi_ = tx_parameters[1];
tx_parameters_.loss_feeder_dB_ = tx_parameters[2];
tx_parameters_.loss_pointing_dB_ = tx_parameters[3];
tx_bitrate_bps_ = tx_parameters[4];

rx_parameters_.gain_dBi_ = rx_parameters[0];
rx_parameters_.loss_feeder_dB_ = rx_parameters[1];
Expand All @@ -42,13 +43,14 @@ Antenna::Antenna(const int component_id, const libra::Quaternion& quaternion_b2c
}

Antenna::Antenna(const int component_id, const libra::Quaternion& quaternion_b2c, const bool is_transmitter, const bool is_receiver,
const double frequency_MHz, const double tx_output_power_W, const AntennaParameters tx_parameters,
const double frequency_MHz, const double tx_bitrate_bps, const double tx_output_power_W, const AntennaParameters tx_parameters,
const double rx_system_noise_temperature_K, const AntennaParameters rx_parameters)
: component_id_(component_id),
quaternion_b2c_(quaternion_b2c),
is_transmitter_(is_transmitter),
is_receiver_(is_receiver),
frequency_MHz_(frequency_MHz),
tx_bitrate_bps_(tx_bitrate_bps),
tx_output_power_W_(tx_output_power_W),
tx_parameters_(tx_parameters),
rx_system_noise_temperature_K_(rx_system_noise_temperature_K),
Expand Down Expand Up @@ -91,9 +93,9 @@ double Antenna::CalcRxGt_dB_K(const double theta_rad, const double phi_rad) cons
}

AntennaGainModel SetAntennaGainModel(const std::string gain_model_name) {
if (gain_model_name == "kIsotropic") {
if (gain_model_name == "ISOTROPIC") {
return AntennaGainModel::kIsotropic;
} else if (gain_model_name == "kRadiationPatternCsv") {
} else if (gain_model_name == "RADIATION_PATTERN_CSV") {
return AntennaGainModel::kRadiationPatternCsv;
} else {
return AntennaGainModel::kIsotropic;
Expand Down
12 changes: 10 additions & 2 deletions src/components/real/communication/antenna.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class Antenna {
* @param [in] rx_parameters: gain, loss_feeder, loss_pointing, system_temperature for RX
*/
Antenna(const int component_id, const libra::Quaternion& quaternion_b2c, const bool is_transmitter, const bool is_receiver,
const double frequency_MHz, const Vector<4> tx_parameters, const Vector<4> rx_parameters);
const double frequency_MHz, const Vector<5> tx_parameters, const Vector<4> rx_parameters);

/**
* @fn Antenna
Expand All @@ -65,13 +65,14 @@ class Antenna {
* @param [in] is_transmitter: Antenna for transmitter or not
* @param [in] is_receiver: Antenna for receiver or not
* @param [in] frequency_MHz: Center Frequency [MHz]
* @param [in] tx_bitrate_bps: Transmit bitrate [bps]
* @param [in] tx_output_power_W: Transmit output power [W]
* @param [in] tx_parameters: TX antenna parameters
* @param [in] rx_system_noise_temperature_K: Receive system noise temperature [K]
* @param [in] rx_parameters: RX antenna parameters
*/
Antenna(const int component_id, const libra::Quaternion& quaternion_b2c, const bool is_transmitter, const bool is_receiver,
const double frequency_MHz, const double tx_output_power_W, const AntennaParameters tx_parameters,
const double frequency_MHz, const double tx_bitrate_bps, const double tx_output_power_W, const AntennaParameters tx_parameters,
const double rx_system_noise_temperature_K, const AntennaParameters rx_parameters);
/**
* @fn ~Antenna
Expand Down Expand Up @@ -103,6 +104,12 @@ class Antenna {
*/
inline double GetFrequency_MHz() const { return frequency_MHz_; }
/**
* @fn GetBitrate
* @brief Return bitrate [bps]
*/
inline double GetBitrate() const { return tx_bitrate_bps_; }
/**
*
* @fn GetQuaternion_b2c
* @brief Return quaternion from body to component
*/
Expand All @@ -128,6 +135,7 @@ class Antenna {
double frequency_MHz_; //!< Center Frequency [MHz]

// Tx info
double tx_bitrate_bps_; //!< Transmit bitrate [bps]
double tx_output_power_W_; //!< Transmit output power [W]
AntennaParameters tx_parameters_; //!< Tx parameters
double tx_eirp_dBW_; //!< Transmit EIRP(Equivalent Isotropic Radiated Power) [dBW]
Expand Down
66 changes: 36 additions & 30 deletions src/components/real/communication/ground_station_calculator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,22 @@ GroundStationCalculator::GroundStationCalculator(const double loss_polarization_

GroundStationCalculator::~GroundStationCalculator() {}

void GroundStationCalculator::Update(const Spacecraft& spacecraft, const Antenna& spacecraft_tx_antenna, const GroundStation& ground_station,
const Antenna& ground_station_rx_antenna) {
void GroundStationCalculator::Update(const Spacecraft& spacecraft, const Antenna& spacecraft_antenna, const GroundStation& ground_station,
const Antenna& ground_station_antenna) {
bool is_visible = ground_station.IsVisible(spacecraft.GetSpacecraftId());
if (is_visible) {
max_bitrate_Mbps_ = CalcMaxBitrate(spacecraft.GetDynamics(), spacecraft_tx_antenna, ground_station, ground_station_rx_antenna);
receive_margin_dB_ = CalcReceiveMarginOnGs(spacecraft.GetDynamics(), spacecraft_tx_antenna, ground_station, ground_station_rx_antenna);
max_bitrate_Mbps_ = CalcMaxBitrate(spacecraft.GetDynamics(), spacecraft_antenna, ground_station, ground_station_antenna);
receive_margin_dB_ = CalcReceiveMarginOnGs(spacecraft.GetDynamics(), spacecraft_antenna, ground_station, ground_station_antenna);
} else {
max_bitrate_Mbps_ = 0.0;
receive_margin_dB_ = -10000.0; // FIXME: which value is suitable?
}
}

// Private functions
double GroundStationCalculator::CalcMaxBitrate(const Dynamics& dynamics, const Antenna& spacecraft_tx_antenna, const GroundStation& ground_station,
const Antenna& ground_station_rx_antenna) {
double cn0_dBHz = CalcCn0OnGs(dynamics, spacecraft_tx_antenna, ground_station, ground_station_rx_antenna);
double GroundStationCalculator::CalcMaxBitrate(const Dynamics& dynamics, const Antenna& spacecraft_antenna, const GroundStation& ground_station,
const Antenna& ground_station_antenna) {
double cn0_dBHz = CalcCn0OnGs(dynamics, spacecraft_antenna, ground_station, ground_station_antenna);

double margin_for_bitrate_dB = cn0_dBHz - (ebn0_dB_ + hardware_deterioration_dB_ + coding_gain_dB_) - margin_requirement_dB_;

Expand All @@ -52,48 +52,54 @@ double GroundStationCalculator::CalcMaxBitrate(const Dynamics& dynamics, const A
}
}

double GroundStationCalculator::CalcReceiveMarginOnGs(const Dynamics& dynamics, const Antenna& spacecraft_tx_antenna,
const GroundStation& ground_station, const Antenna& ground_station_rx_antenna) {
double cn0_dB = CalcCn0OnGs(dynamics, spacecraft_tx_antenna, ground_station, ground_station_rx_antenna);
double cn0_requirement_dB = ebn0_dB_ + hardware_deterioration_dB_ + coding_gain_dB_ + 10.0 * log10(downlink_bitrate_bps_);
double GroundStationCalculator::CalcReceiveMarginOnGs(const Dynamics& dynamics, const Antenna& spacecraft_antenna,
const GroundStation& ground_station, const Antenna& ground_station_antenna) {
double cn0_dB = CalcCn0OnGs(dynamics, spacecraft_antenna, ground_station, ground_station_antenna);
double cn0_requirement_dB = ebn0_dB_ + hardware_deterioration_dB_ + coding_gain_dB_ + 10.0 * log10(spacecraft_antenna.GetBitrate());
return cn0_dB - cn0_requirement_dB;
}

double GroundStationCalculator::CalcCn0OnGs(const Dynamics& dynamics, const Antenna& spacecraft_tx_antenna, const GroundStation& ground_station,
const Antenna& ground_station_rx_antenna) {
if (!spacecraft_tx_antenna.IsTransmitter() || !ground_station_rx_antenna.IsReceiver()) {
// Check compatibility of transmitter and receiver
return 0.0f;
}

double GroundStationCalculator::CalcCn0OnGs(const Dynamics& dynamics, const Antenna& spacecraft_antenna, const GroundStation& ground_station,
const Antenna& ground_station_antenna) {
// Free space path loss
Vector<3> sc_pos_i = dynamics.GetOrbit().GetPosition_i_m();
Vector<3> gs_pos_i = ground_station.GetPosition_i_m();
double dist_sc_gs_km = CalcNorm(sc_pos_i - gs_pos_i) / 1000.0;
double loss_space_dB = -20.0 * log10(4.0 * libra::pi * dist_sc_gs_km / (300.0 / spacecraft_tx_antenna.GetFrequency_MHz() / 1000.0));
double loss_space_dB = -20.0 * log10(4.0 * libra::pi * dist_sc_gs_km / (300.0 / spacecraft_antenna.GetFrequency_MHz() / 1000.0));

// GS direction on SC TX antenna frame
Vector<3> sc_to_gs_i = gs_pos_i - sc_pos_i;
sc_to_gs_i = libra::Normalize(sc_to_gs_i);
Quaternion q_i_to_sc_ant = spacecraft_tx_antenna.GetQuaternion_b2c() * dynamics.GetAttitude().GetQuaternion_i2b();
Quaternion q_i_to_sc_ant = spacecraft_antenna.GetQuaternion_b2c() * dynamics.GetAttitude().GetQuaternion_i2b();
Vector<3> gs_direction_on_sc_frame = q_i_to_sc_ant.FrameConversion(sc_to_gs_i);
double theta_on_sc_antenna_rad = acos(gs_direction_on_sc_frame[2]);
double phi_on_sc_antenna_rad = acos(gs_direction_on_sc_frame[0] / sin(theta_on_sc_antenna_rad));
double phi_on_sc_antenna_rad = atan2(gs_direction_on_sc_frame[1], gs_direction_on_sc_frame[0]);

// SC direction on GS RX antenna frame
Vector<3> gs_to_sc_ecef = dynamics.GetOrbit().GetPosition_ecef_m() - ground_station.GetPosition_ecef_m();
gs_to_sc_ecef = libra::Normalize(gs_to_sc_ecef);
Quaternion q_ecef_to_gs_ant = ground_station_rx_antenna.GetQuaternion_b2c() * ground_station.GetGeodeticPosition().GetQuaternionXcxfToLtc();
Quaternion q_ecef_to_gs_ant = ground_station_antenna.GetQuaternion_b2c() * ground_station.GetGeodeticPosition().GetQuaternionXcxfToLtc();
Vector<3> sc_direction_on_gs_frame = q_ecef_to_gs_ant.FrameConversion(gs_to_sc_ecef);
double theta_on_gs_antenna_rad = acos(sc_direction_on_gs_frame[2]);
double phi_on_gs_antenna_rad = acos(sc_direction_on_gs_frame[0] / sin(theta_on_gs_antenna_rad));

// Calc CN0
double cn0_dBHz = spacecraft_tx_antenna.CalcTxEirp_dBW(theta_on_sc_antenna_rad, phi_on_sc_antenna_rad) + loss_space_dB + loss_polarization_dB_ +
loss_atmosphere_dB_ + loss_rainfall_dB_ + loss_others_dB_ +
ground_station_rx_antenna.CalcRxGt_dB_K(theta_on_gs_antenna_rad, phi_on_gs_antenna_rad) -
10.0 * log10(environment::boltzmann_constant_J_K);
return cn0_dBHz;
double phi_on_gs_antenna_rad = atan2(sc_direction_on_gs_frame[1], sc_direction_on_gs_frame[0]);

if (spacecraft_antenna.IsTransmitter()) {
// Calc CN0
double cn0_dBHz = spacecraft_antenna.CalcTxEirp_dBW(theta_on_sc_antenna_rad, phi_on_sc_antenna_rad) + loss_space_dB + loss_polarization_dB_ +
loss_atmosphere_dB_ + loss_rainfall_dB_ + loss_others_dB_ +
ground_station_antenna.CalcRxGt_dB_K(theta_on_gs_antenna_rad, phi_on_gs_antenna_rad) -
10.0 * log10(environment::boltzmann_constant_J_K);
return cn0_dBHz;
} else {
// Calc CN0
double testA = ground_station_antenna.CalcTxEirp_dBW(theta_on_gs_antenna_rad, phi_on_gs_antenna_rad);
double testB = spacecraft_antenna.CalcRxGt_dB_K(theta_on_sc_antenna_rad, phi_on_sc_antenna_rad);
double cn0_dBHz = ground_station_antenna.CalcTxEirp_dBW(theta_on_gs_antenna_rad, phi_on_gs_antenna_rad) + loss_space_dB + loss_polarization_dB_ +
loss_atmosphere_dB_ + loss_rainfall_dB_ + loss_others_dB_ +
spacecraft_antenna.CalcRxGt_dB_K(theta_on_sc_antenna_rad, phi_on_sc_antenna_rad) -
10.0 * log10(environment::boltzmann_constant_J_K);
return cn0_dBHz;
}
}

std::string GroundStationCalculator::GetLogHeader() const {
Expand Down
32 changes: 16 additions & 16 deletions src/components/real/communication/ground_station_calculator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ class GroundStationCalculator : public ILoggable {
* @fn Update
* @brief Update maximum bitrate calculation
* @param [in] spacecraft: Spacecraft information
* @param [in] spacecraft_tx_antenna: Antenna mounted on spacecraft
* @param [in] spacecraft_antenna: Antenna mounted on spacecraft
* @param [in] ground_station: Ground station information
* @param [in] ground_station_rx_antenna: Antenna mounted on ground station
* @param [in] ground_station_antenna: Antenna mounted on ground station
*/
void Update(const Spacecraft& spacecraft, const Antenna& spacecraft_tx_antenna, const GroundStation& ground_station,
const Antenna& ground_station_rx_antenna);
void Update(const Spacecraft& spacecraft, const Antenna& spacecraft_antenna, const GroundStation& ground_station,
const Antenna& ground_station_antenna);

// Override ILoggable TODO: Maybe we don't need logabble, and this class should be used as library.
/**
Expand Down Expand Up @@ -104,36 +104,36 @@ class GroundStationCalculator : public ILoggable {
* @fn CalcMaxBitrate
* @brief Calculate the maximum bitrate
* @param [in] dynamics: Spacecraft dynamics information
* @param [in] spacecraft_tx_antenna: Tx Antenna mounted on spacecraft
* @param [in] spacecraft_antenna: Tx Antenna mounted on spacecraft
* @param [in] ground_station: Ground station information
* @param [in] ground_station_rx_antenna: Rx Antenna mounted on ground station
* @param [in] ground_station_antenna: Rx Antenna mounted on ground station
* @return Max bitrate [Mbps]
*/
double CalcMaxBitrate(const Dynamics& dynamics, const Antenna& spacecraft_tx_antenna, const GroundStation& ground_station,
const Antenna& ground_station_rx_antenna);
double CalcMaxBitrate(const Dynamics& dynamics, const Antenna& spacecraft_antenna, const GroundStation& ground_station,
const Antenna& ground_station_antenna);
/**
* @fn CalcReceiveMarginOnGs
* @brief Calculate receive margin at the ground station
* @param [in] dynamics: Spacecraft dynamics information
* @param [in] spacecraft_tx_antenna: Tx Antenna mounted on spacecraft
* @param [in] spacecraft_antenna: Tx Antenna mounted on spacecraft
* @param [in] ground_station: Ground station information
* @param [in] ground_station_rx_antenna: Rx Antenna mounted on ground station
* @param [in] ground_station_antenna: Rx Antenna mounted on ground station
* @return Receive margin [dB]
*/
double CalcReceiveMarginOnGs(const Dynamics& dynamics, const Antenna& spacecraft_tx_antenna, const GroundStation& ground_station,
const Antenna& ground_station_rx_antenna);
double CalcReceiveMarginOnGs(const Dynamics& dynamics, const Antenna& spacecraft_antenna, const GroundStation& ground_station,
const Antenna& ground_station_antenna);

/**
* @fn CalcCn0
* @brief Calculate CN0 (Carrier to Noise density ratio) of received signal at the ground station
* @param [in] dynamics: Spacecraft dynamics information
* @param [in] spacecraft_tx_antenna: Tx Antenna mounted on spacecraft
* @param [in] spacecraft_antenna: Tx Antenna mounted on spacecraft
* @param [in] ground_station: Ground station information
* @param [in] ground_station_rx_antenna: Rx Antenna mounted on ground station
* @param [in] ground_station_antenna: Rx Antenna mounted on ground station
* @return CN0 [dB]
*/
double CalcCn0OnGs(const Dynamics& dynamics, const Antenna& spacecraft_tx_antenna, const GroundStation& ground_station,
const Antenna& ground_station_rx_antenna);
double CalcCn0OnGs(const Dynamics& dynamics, const Antenna& spacecraft_antenna, const GroundStation& ground_station,
const Antenna& ground_station_antenna);
};

#endif // S2E_COMPONENTS_REAL_COMMUNICATION_GROUND_STATION_CALCULATOR_HPP_
3 changes: 2 additions & 1 deletion src/components/real/communication/initialize_antenna.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Antenna InitAntenna(const int antenna_id, const std::string file_name) {
bool is_receiver = antenna_conf.ReadBoolean(Section, "is_receiver");
double frequency_MHz = antenna_conf.ReadDouble(Section, "frequency_MHz");

double tx_bitrate_bps = antenna_conf.ReadDouble(Section, "tx_bitrate_bps");
double tx_output_power_W = antenna_conf.ReadDouble(Section, "tx_output_W");
double rx_system_noise_temperature_K = antenna_conf.ReadDouble(Section, "rx_system_noise_temperature_K");

Expand Down Expand Up @@ -72,7 +73,7 @@ Antenna InitAntenna(const int antenna_id, const std::string file_name) {
rx_parameters.antenna_gain_model = AntennaGainModel::kIsotropic;
}

Antenna antenna(antenna_id, quaternion_b2c, is_transmitter, is_receiver, frequency_MHz, tx_output_power_W, tx_parameters,
Antenna antenna(antenna_id, quaternion_b2c, is_transmitter, is_receiver, frequency_MHz, tx_bitrate_bps, tx_output_power_W, tx_parameters,
rx_system_noise_temperature_K, rx_parameters);
return antenna;
}
2 changes: 2 additions & 0 deletions src/simulation/ground_station/ground_station.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ std::string GroundStation::GetLogHeader() const {
std::string legend = head + "sc" + std::to_string(i) + "_visible_flag";
str_tmp += WriteScalar(legend);
}
str_tmp += WriteVector("gs_pos", "eci", "m", 3);
return str_tmp;
}

Expand All @@ -86,5 +87,6 @@ std::string GroundStation::GetLogValue() const {
for (unsigned int i = 0; i < number_of_spacecraft_; i++) {
str_tmp += WriteScalar(is_visible_.at(i));
}
str_tmp += WriteVector(position_i_m_);
return str_tmp;
}