error:NullReferenceException: Object reference not set to an instance of an object

First, I want to send a string type data service request from Unity to the pose estimation server, then receive the pose estimation return. In the pose estimation callback function, I will send the pose estimation return to the MoveIt! service server, which will return the robotic arm’s planned trajectory, and then execute it in Unity.`using System;
using System.Collections;
using System.Linq;
using RosMessageTypes.Geometry;
using RosMessageTypes.RokaeWithGripperMoveitConfig;
using Unity.Robotics.ROSTCPConnector;
using Unity.Robotics.ROSTCPConnector.ROSGeometry;
using UnityEngine;
using UnityEngine.Perception.GroundTruth;
using RosMessageTypes.Std;

public class Book_PoseEstimate : MonoBehaviour
{
public PerceptionCamera perceptionCamera;
int index = 0;
public string images_path = “/home/jimmy/.config/unity3d/UnityRobotics/PickAndPlace/solo/sqeuence.0/step_”;
// Hardcoded variables
const int k_NumRobotJoints = 7;
const float k_JointAssignmentWait = 0.2f;
const float k_PoseAssignmentWait = 0.25f;
public static readonly string LinkNames = { “world/xMatePro7_base/xMatePro7_link1”, “/xMatePro7_link2”, “/xMatePro7_link3”, “/xMatePro7_link4”, “/xMatePro7_link5”, “/xMatePro7_link6”, “/xMatePro7_link7”};
// Variables required for ROS communication
[SerializeField]
string m_RosServiceName = “rokae_moveit”;
public string RosServiceName { get => m_RosServiceName; set => m_RosServiceName = value; }

[SerializeField]
GameObject m_Rokae;
public GameObject Rokae { get => m_Rokae; set => m_Rokae = value; }
[SerializeField]
GameObject m_Target;
public GameObject Target { get => m_Target; set => m_Target = value; }
[SerializeField]
GameObject m_TargetPlacement;
public GameObject TargetPlacement { get => m_TargetPlacement; set => m_TargetPlacement = value; }

// Assures that the gripper is always positioned above the m_Target cube before grasping.
readonly Quaternion m_PickOrientation = Quaternion.Euler(90, 90, 0);
readonly Vector3 m_PickPoseOffset = Vector3.up * 0.19f;  

// Articulation Bodies
ArticulationBody[] m_JointArticulationBodies;
ArticulationBody m_LeftGripper;
ArticulationBody m_RightGripper;

// ROS Connector
ROSConnection m_Ros;

void Start()
{
    // Get ROS connection static instance
    m_Ros = ROSConnection.GetOrCreateInstance();
    // m_Ros.RegisterRosService<MoverServiceRequest, MoverServiceResponse>(m_RosServiceName);
    m_JointArticulationBodies = new ArticulationBody[k_NumRobotJoints];

    var linkName = string.Empty;
    for (var i = 0; i < k_NumRobotJoints; i++)
    {
        linkName += LinkNames[i];
        m_JointArticulationBodies[i] = m_Rokae.transform.Find(linkName).GetComponent<ArticulationBody>();
    }

    // Find left and right fingers
    var rightGripper = linkName + "/base_link/finger1_link";
    var leftGripper = linkName + "/base_link/finger2_link";

    m_RightGripper = m_Rokae.transform.Find(rightGripper).GetComponent<ArticulationBody>();
    m_LeftGripper = m_Rokae.transform.Find(leftGripper).GetComponent<ArticulationBody>();
}

void CloseGripper()
{
    var leftDrive = m_LeftGripper.xDrive;
    var rightDrive = m_RightGripper.xDrive;

    leftDrive.target = 0.025f;
    leftDrive.targetVelocity = 0.0f;
    rightDrive.target = 0.025f;
    rightDrive.targetVelocity = 0.0f;

    m_LeftGripper.xDrive = leftDrive;
    m_RightGripper.xDrive = rightDrive;
}

void OpenGripper()
{
    var leftDrive = m_LeftGripper.xDrive;
    var rightDrive = m_RightGripper.xDrive;

    leftDrive.target = 0.0f;
    rightDrive.target = -0.0f;

    m_LeftGripper.xDrive = leftDrive;
    m_RightGripper.xDrive = rightDrive;
}

RokaeMoveitJointsMsgMsg CurrentJointConfig()  
{
    var joints = new RokaeMoveitJointsMsgMsg();

    for (var i = 0; i < k_NumRobotJoints; i++)
    {
        joints.joints[i] = m_JointArticulationBodies[i].jointPosition[0];
    }

    return joints;
}

public void PoseEstimation()
{
    Debug.Log($"press 's' start Perception Camera get {index} frame...");
    images_path = string.Concat(images_path, index);
    PoseEstimationServiceRequest request = new PoseEstimationServiceRequest();
    request.image_path = images_path;
    // Debug.Log(request);
    m_Ros.SendServiceMessage<PoseEstimationServiceResponse>("pose_estimation_service", request, PoseEstimationCallback);
    Debug.Log("send images_path to ROS service...");
}

void PoseEstimationCallback(PoseEstimationServiceResponse response)
{
    if (response != null)
    {   
        Debug.Log("Pose Estimation Service successfully returned pose estimation result!");
        var estimatedPosition = Camera.main.transform.TransformPoint(response.estimated_pose.position.From<RUF>());
        var estimatedRotation = Camera.main.transform.rotation * response.estimated_pose.orientation.From<RUF>();
        PublishJoints(estimatedPosition, estimatedRotation);
    }
    Debug.Log("Pose Estimation Service failed to return pose estimation result!");
}

public void PublishJoints(Vector3 position, Quaternion rotation)
{
    var request = new MoverServiceRequest();
    request.joints_input = CurrentJointConfig();

    // Pick Pose
    request.pick_pose = new PoseMsg
    {
        position = (position + m_PickPoseOffset).To<FLU>(),
        // The hardcoded x/z angles assure that the gripper is always positioned above the target cube before grasping.
        orientation = (Quaternion.Euler(180, rotation.eulerAngles.y-180, 0)).To<FLU>()
    };
    // Place Pose
    request.place_pose = new PoseMsg
    {
        position = (m_TargetPlacement.transform.position + m_PickPoseOffset * 2).To<FLU>(),
        orientation = (Quaternion.Euler(180, m_TargetPlacement.transform.eulerAngles.y-90, 0) ).To<FLU>()
    };
    // Debug.Log(request);
    m_Ros.SendServiceMessage<MoverServiceResponse>(m_RosServiceName, request, TrajectoryResponse);
}

void TrajectoryResponse(MoverServiceResponse response)
{
    if (response.trajectories.Length > 0)
    {
        Debug.Log("Trajectory returned.");
        StartCoroutine(ExecuteTrajectories(response));
    }
    else
    {
        Debug.LogError("No trajectory returned from MoverService.");
    }
}

IEnumerator ExecuteTrajectories(MoverServiceResponse response)
{
    if (response.trajectories != null)
    {
        // For every trajectory plan returned
        for (var poseIndex = 0; poseIndex < response.trajectories.Length; poseIndex++)
        {
            // For every robot pose in trajectory plan
            foreach (var t in response.trajectories[poseIndex].joint_trajectory.points)
            {
                var jointPositions = t.positions;
                var result = jointPositions.Select(r => (float)r * Mathf.Rad2Deg).ToArray();

                // Set the joint values for every joint
                for (var joint = 0; joint < m_JointArticulationBodies.Length; joint++)
                {
                    var joint1XDrive = m_JointArticulationBodies[joint].xDrive;
                    joint1XDrive.target = result[joint];
                    m_JointArticulationBodies[joint].xDrive = joint1XDrive;
                }

                // Wait for robot to achieve pose for all joint assignments
                yield return new WaitForSeconds(k_JointAssignmentWait);
            }

            // Close the gripper if completed executing the trajectory for the Grasp pose
            if (poseIndex == (int)Poses.Grasp)
            {
                yield return new WaitForSeconds(k_JointAssignmentWait);
                // yield return new WaitForSeconds(2.0f);
                CloseGripper();
                yield return new WaitForSeconds(2.0f);
            }

            // Wait for the robot to achieve the final pose from joint assignment
           yield return new WaitForSeconds(k_PoseAssignmentWait);
        }

        // All trajectories have been executed, open the gripper to place the target cube
        OpenGripper();
    }
}

enum Poses
{
    PreGrasp,
    Grasp,
    PickUp,
    Place
}

}
`


And the button settings are shown above.

When asking a question, it’s best to provide as much information as possible:

  • Share your entire script in a code block:
```csharp
// your copy/pasted code here
```
  • Include any errors you encountered and their exact messages.
  • Explain what you were trying to achieve.
  • Describe what actually happened versus what you expected.
  • List any troubleshooting steps you’ve already attempted.

This not only will make your question concrete, but will also show people that you respect their time:

  • Using a code block allows others to easily copy and paste your script rather than having to type it from scratch. Providing the full script also enables them to run it on their own machines.
  • Sharing the exact error message helps identify the issue more efficiently.
  • Clearly stating your goal prevents guesswork about what you’re trying to accomplish.
  • Describing what actually happened (rather than just what you expected) helps them reproduce the issue.
  • Sharing what you’ve already tried prevents them from wasting time on the same solutions.

Thanks for your reply. I have solved this problem by just add a line of code m_Ros.RegisterRosService<PoseEstimationServiceRequest, PoseEstimationServiceResponse>("pose_estimation_service");