Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00023 #include "sr_ronex_controllers/spi_sensor_read_controller.h"
00024 #include "pluginlib/class_list_macros.h"
00025 #include "std_msgs/Float64MultiArray.h"
00026 #include <utility>
00027 #include <stdexcept>
00028 #include <string>
00029 #include <vector>
00030
00031 PLUGINLIB_EXPORT_CLASS(ronex::SPISensorReadController, controller_interface::ControllerBase)
00032
00033 namespace ronex
00034 {
00035 const int SPISensorReadController::default_spi_channel_ = 1;
00036 const size_t SPISensorReadController::sensor_message_length_ = 2;
00037 const size_t SPISensorReadController::spi_mode_ = 1;
00038 const double SPISensorReadController::publish_rate_ = 100;
00039
00040
00041 bool SPISensorReadController::init(ros_ethercat_model::RobotStateInterface* robot, ros::NodeHandle &n)
00042 {
00043 if ( !pre_init_(robot, n) )
00044 return false;
00045 chip_select_masks_.resize(NUM_SPI_OUTPUTS);
00046 chip_select_masks_[0] = PIN_OUTPUT_STATE_CS_0;
00047 chip_select_masks_[1] = PIN_OUTPUT_STATE_CS_1;
00048 chip_select_masks_[2] = PIN_OUTPUT_STATE_CS_2;
00049 chip_select_masks_[3] = PIN_OUTPUT_STATE_CS_3;
00050 std::string ronex_id;
00051 node_.getParam("ronex_id", ronex_id);
00052 std::stringstream topic_name;
00053 topic_name << "sensor_message_" << ronex_id;
00054 standard_commands_.assign(NUM_SPI_OUTPUTS, SplittedSPICommand());
00055
00056 if (!n.hasParam("SPI_sensor_channel"))
00057 {
00058 ROS_WARN_STREAM("No SPI channel is defined. Will assume a single channel " << default_spi_channel_);
00059 spi_channel_.push_back(default_spi_channel_);
00060 }
00061 else
00062 {
00063 n.getParam("SPI_sensor_channel", spi_channel_);
00064 }
00065 for (std::vector<int>::const_iterator channel_iter = spi_channel_.begin(); channel_iter != spi_channel_.end();
00066 ++channel_iter)
00067 {
00068 if (*channel_iter < 0 || *channel_iter > NUM_SPI_OUTPUTS)
00069 {
00070 ROS_FATAL("spi channel parameter should be larger than or equal 0 "
00071 "and smaller than number of SPI outputs");
00072 return false;
00073 }
00074 standard_commands_[*channel_iter].packet.num_bytes = sensor_message_length_;
00075 topic_name << "_" << *channel_iter;
00076 }
00077
00078 sensor_data_publisher_.init(n, topic_name.str(), 1);
00079 first_run_ = true;
00080
00081 return true;
00082 }
00083
00084 void SPISensorReadController::update(const ros::Time& time, const ros::Duration& dur)
00085 {
00086 if (first_run_)
00087 {
00088 first_run_ = false;
00089 spi_->command_->command_type = static_cast<int16u>(1);
00090
00091
00092 for (std::vector<int>::const_iterator channel_iter = spi_channel_.begin(); channel_iter != spi_channel_.end();
00093 ++channel_iter)
00094 {
00095 standard_commands_[*channel_iter].packet.SPI_config = 1;
00096 standard_commands_[*channel_iter].packet.clock_divider = static_cast<int16u>(16);
00097 standard_commands_[*channel_iter].packet.SPI_config |= static_cast<int16u>(0);
00098 standard_commands_[*channel_iter].packet.SPI_config |= 0;
00099 standard_commands_[*channel_iter].packet.SPI_config |= 0;
00100 standard_commands_[*channel_iter].packet.inter_byte_gap = 0;
00101 cmd_pin_output_states_pre_ = 0;
00102 cmd_pin_output_states_post_ |= chip_select_masks_[*channel_iter];
00103 }
00104 }
00105
00106
00107
00108 sensor_msg_.data.resize(spi_channel_.size());
00109 for (std::vector<int>::const_iterator channel_iter = spi_channel_.begin(); channel_iter != spi_channel_.end();
00110 ++channel_iter)
00111 {
00112
00113 if (status_queue_[*channel_iter].size() > 0)
00114 {
00115
00116 if (loop_count_ == status_queue_[*channel_iter].front().second.loop_number + 2 )
00117 {
00118
00119
00120 if (spi_->state_->command_type == RONEX_COMMAND_02000002_COMMAND_TYPE_NORMAL)
00121 {
00122 status_queue_[*channel_iter].back().second.received = true;
00123 status_queue_[*channel_iter].back().second.packet =
00124 SPI_PACKET_IN(spi_->state_->info_type.status_data.spi_in[*channel_iter]);
00125 unsigned int high_byte =
00126 static_cast<unsigned int>(status_queue_[*channel_iter].back().second.packet.data_bytes[0] & 0x3F);
00127 unsigned int low_byte =
00128 static_cast<unsigned int>(status_queue_[*channel_iter].back().second.packet.data_bytes[1]);
00129 ROS_DEBUG_STREAM("sensor value is " << (high_byte << 8 | low_byte));
00130
00131 sensor_msg_.data[channel_iter - spi_channel_.begin()] =
00132 (static_cast<double>((high_byte << 8 | low_byte) *2.0*M_PI) / 16384);
00133 status_queue_[*channel_iter].pop();
00134 }
00135 }
00136 }
00137 try
00138 {
00139 standard_commands_[*channel_iter].packet.data_bytes[0] = 0xFF;
00140 standard_commands_[*channel_iter].packet.data_bytes[1] = 0xFF;
00141 command_queue_[*channel_iter].push(standard_commands_[*channel_iter]);
00142 }
00143 catch(...)
00144 {
00145 ROS_ERROR_STREAM("something bad happened");
00146 }
00147 try
00148 {
00149 status_queue_[*channel_iter].push(std::pair<SplittedSPICommand, SPIResponse>());
00150 status_queue_[*channel_iter].back().first = command_queue_[*channel_iter].front();
00151 status_queue_[*channel_iter].back().second.received = false;
00152 status_queue_[*channel_iter].back().second.loop_number = loop_count_;
00153
00154
00155 copy_splitted_to_cmd_(*channel_iter);
00156 }
00157 catch(...)
00158 {
00159 ROS_ERROR_STREAM("error while copy_splitted_to_cmd_");
00160 }
00161 command_queue_[*channel_iter].pop();
00162 }
00163
00164 if (publish_rate_ > 0.0 && last_publish_time_ + ros::Duration(1.0/publish_rate_) < time)
00165 {
00166 if (sensor_data_publisher_.trylock())
00167 {
00168 last_publish_time_ = last_publish_time_ + ros::Duration(1.0/publish_rate_);
00169
00170 sensor_data_publisher_.msg_ = sensor_msg_;
00171 sensor_data_publisher_.unlockAndPublish();
00172 }
00173 }
00174 loop_count_++;
00175 }
00176 std::vector<double> SPISensorReadController::get_sensor_value()
00177 {
00178 return sensor_msg_.data;
00179 }
00180
00181 std::vector<int> SPISensorReadController::get_spi_channel()
00182 {
00183 return spi_channel_;
00184 }
00185 }